-
Notifications
You must be signed in to change notification settings - Fork 198
feat: multi-account yield support #11665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Replace useEffect with useMemo for default account selection in YieldAccountContext (per CLAUDE.md guidelines) - Extract duplicate URL sync logic to useYieldAccountSync hook - Fix aggregate calculation in YieldOpportunityStats to sum all active/locked balances across accounts (was using find instead of filter) - Ensure feature flag properly gates single-account filtering - Fix type inconsistency in useYieldAccount hook (return 0 not undefined) - Remove duplicate account column in YieldActivePositions table - Add comprehensive tests for yield utils Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…selector - YieldSuccess now accepts accountId and includes it in "View Position" navigation URL - Updated all YieldSuccess callers (YieldForm, YieldEnterModal, YieldActionModal) - Fixed YieldEnterModal to fallback to first available account when no accountId prop - Show validator name/logo for staking positions in YieldActivePositions table - Route to yield detail with accountId in query params when clicking positions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds multi-account yield support: account context with URL sync, accountId plumbing through UI and transaction flows, account-scoped balance queries, per-account positions aggregation, new hooks/queries, tests, translations, and feature-flag gating. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI as Yield UI
participant Hook as useYieldAccountSync
participant Context as YieldAccountContext
participant Query as useAllYieldBalances
participant API as Yield API
User->>UI: selects account in AccountSelector
UI->>Hook: handleAccountChange(newAccountId)
Hook->>Context: setAccountId(newAccountId)
Hook->>UI: push URL ?accountId=newAccountId
Context-->>UI: accountId updated
UI->>Query: fetch balances(targetAccountIds=[newAccountId])
Query->>API: GET /balances?accountIds=...
API-->>Query: balances
Query-->>UI: balances response
UI-->>User: render per-account positions & stats
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (2)
🧰 Additional context used📓 Path-based instructions (6)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{tsx,jsx}📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)
Files:
**/*.{js,jsx,ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)
Files:
**/*.{jsx,tsx}📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
Files:
**/*.tsx📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
Files:
🧠 Learnings (29)📓 Common learnings📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2026-01-08T23:17:05.494ZApplied to files:
📚 Learning: 2025-10-21T17:11:18.087ZApplied to files:
📚 Learning: 2025-10-07T03:44:27.350ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-07-29T10:27:23.424ZApplied to files:
📚 Learning: 2025-08-21T22:15:25.918ZApplied to files:
📚 Learning: 2025-11-24T21:20:44.637ZApplied to files:
📚 Learning: 2025-09-16T09:32:21.333ZApplied to files:
📚 Learning: 2025-08-05T22:41:35.473ZApplied to files:
📚 Learning: 2025-08-22T13:00:23.679ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-08-15T07:51:16.374ZApplied to files:
📚 Learning: 2025-08-15T07:51:16.374ZApplied to files:
📚 Learning: 2025-08-15T07:51:16.374ZApplied to files:
📚 Learning: 2025-09-04T10:18:34.140ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-08-21T22:16:55.203ZApplied to files:
📚 Learning: 2025-11-24T21:20:04.979ZApplied to files:
📚 Learning: 2025-12-27T16:02:52.792ZApplied to files:
📚 Learning: 2026-01-15T09:59:33.508ZApplied to files:
📚 Learning: 2025-09-08T15:53:09.362ZApplied to files:
📚 Learning: 2025-09-12T12:00:33.924ZApplied to files:
📚 Learning: 2025-09-12T12:00:33.924ZApplied to files:
📚 Learning: 2025-08-10T21:09:25.643ZApplied to files:
📚 Learning: 2025-09-02T00:02:44.889ZApplied to files:
📚 Learning: 2025-07-29T15:04:28.083ZApplied to files:
🧬 Code graph analysis (2)src/pages/Yields/components/YieldForm.tsx (2)
src/pages/Yields/components/YieldEnterModal.tsx (2)
⏰ 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)
🔇 Additional comments (4)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this 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/YieldPositionCard.tsx`:
- Line 63: The guard "if (accountNumber === undefined) return undefined" in
YieldPositionCard is unreachable because useYieldAccount always returns
accountNumber as a number (defaults to 0); remove this conditional and any early
return that depends on accountNumber being undefined to simplify the component
and rely on the numeric value from useYieldAccount instead.
🧹 Nitpick comments (3)
src/pages/Yields/components/YieldActionModal.tsx (1)
46-46: UseAccountIdtype instead ofstringfor type consistency.The
accountIdprop is typed asstring, butYieldSuccessand other components in this PR useAccountIdfrom@shapeshiftoss/caip. Using the nominalAccountIdtype ensures type safety across the yield flow.Suggested fix
Add the import at the top of the file:
import type { AccountId } from '@shapeshiftoss/caip'Then update the prop type:
type YieldActionModalProps = { isOpen: boolean onClose: () => void yieldItem: AugmentedYieldDto action: 'enter' | 'exit' | 'manage' amount: string assetSymbol: string assetLogoURI?: string validatorAddress?: string validatorName?: string validatorLogoURI?: string passthrough?: string manageActionType?: string - accountId?: string + accountId?: AccountId }src/pages/Yields/YieldAssetDetails.tsx (1)
115-118: Minor inconsistency with YieldDetail.tsx balance fetching logic.In
YieldDetail.tsx(line 68-71), whenisYieldMultiAccountEnabledis false,balanceAccountIdsreturnsundefinedifavailableAccountsis empty. Here, it returnsaccountIdsForAssetdirectly (potentially an empty array).This difference may cause inconsistent behavior in
useAllYieldBalancesdepending on how it handles empty arrays vs.undefined. Consider aligning the logic:const balanceAccountIds = useMemo(() => { - if (!isYieldMultiAccountEnabled) return accountIdsForAsset + if (!isYieldMultiAccountEnabled) return accountIdsForAsset.length > 0 ? accountIdsForAsset : undefined return selectedAccountId ? [selectedAccountId] : accountIdsForAsset }, [isYieldMultiAccountEnabled, selectedAccountId, accountIdsForAsset])src/pages/Yields/components/YieldActivePositions.tsx (1)
87-141: Validator info may be lost when aggregating multiple validators.When a user has positions with multiple validators in the same yield, only the first validator's info is preserved due to the
existing.validatorAddress ?? validator?.addresspattern. If the intent is to show separate positions per validator, consider grouping by(accountId, validatorAddress)instead of justaccountId.If showing one aggregate per account is intentional (with "first validator wins"), this is acceptable but worth documenting.
- Remove toUserCurrency utility (use inline bnOrZero().times().toFixed() pattern) - Remove trivial lookup table tests for getTransactionButtonText - Keep meaningful tests for edge cases, fallbacks, and actual logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
accountNumber always returns a number (defaults to 0) from useYieldAccount, so the undefined check is unreachable. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
premiumjibles
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Tested yields page with no wallet connected 👍
-
Tested connect wallet flow via stake modal 👍
-
Tested switching accounts on an ETH opportunity 👍
-
Tested staking on cosmos without multiple accounts (no selector appears) 👍
-
Tested URL account selection updates when switching wallets 👍
-
Tested URL account selection persists on refresh through URL 👍
-
Tested URL account selection handles refresh then connect to different wallet 👍
-
Tested yield page for an opportunity show specific values per account but aggregate yield page shows total position here 👍
-
Tested Yield modal routes to correct account when one is selected on specific yield page jam 👍
-
[Non-blocking] minor issue with staking modal state. The modal allows you to switch account when you're halfway through a stake. Which let's you get into a bit of an awkward state where all the buttons are disabled, even if you switch back to your original correct account. Ideally we disable that account selector on the modal once the user hits "enter". Minor though, it doesn't allow the user to do anything bad.
* feat: first ralph * fix: show only default validator balance for yields in DeFi tab Use DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID for Cosmos/Solana yields, falling back to validators[0] for others. This matches the pattern used throughout the yield feature (YieldForm, YieldPositionCard). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this 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/react-queries/queries/yieldxyz/useYields.ts`:
- Around line 59-60: In useYields, short-circuit when isEnabled is false to
avoid processing or returning cached yield data: check the isEnabled flag early
in the hook (before any useMemo/useQuery/data transformations) and return a
disabled/no-data result (e.g., null/undefined or an object matching the disabled
shape) so memoized computations and cached React Query data are not exposed;
apply the same pattern to the other memo/processing block referenced at the
second occurrence (the block around line 92) to ensure both places respect
isEnabled.
🧹 Nitpick comments (6)
src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (2)
95-101: Consider extracting APY comparison to a helper for clarity.The nested ternary for APY comparison works correctly (keeping the higher APY), but could be more readable.
🔧 Optional: Extract to helper function
- const currentApy = aggregatedByAssetId[inputAssetId].apy - aggregatedByAssetId[inputAssetId].apy = currentApy - ? bnOrZero(currentApy).gt(yieldItem.rewardRate.total) - ? currentApy - : yieldItem.rewardRate.total.toString() - : yieldItem.rewardRate.total.toString() + const currentApy = aggregatedByAssetId[inputAssetId].apy + const newApy = yieldItem.rewardRate.total.toString() + aggregatedByAssetId[inputAssetId].apy = !currentApy || bnOrZero(newApy).gt(currentApy) + ? newApy + : currentApy
131-145: Debug logging should be removed or gated before production.While useful during development,
console.debugwithJSON.stringifyon potentially large datasets may impact performance. Consider removing before merging or gating behind a development flag.Based on learnings, gomesalexandre prefers console.error for debugging over structured logging, but this is debug-level output that could be removed for production.
src/components/StakingVaults/DeFiEarn.tsx (1)
69-82: Consider removing or conditionally gating debug logging.Multiple
console.debugcalls withJSON.stringifyon potentially large datasets. Same consideration as the previous file.Also applies to: 112-125
src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx (3)
122-137: Type assertionas unknown as UnifiedPosition[]is a code smell.The conversion from
YieldOpportunityDisplaytoUnifiedPositionuses a double cast which bypasses type checking. This could hide type mismatches at runtime.♻️ Consider creating an explicit mapping type or interface
Instead of
as unknown as UnifiedPosition[], consider:
- Creating a mapper function that explicitly constructs a valid
UnifiedPosition:const mapYieldToUnifiedPosition = (y: YieldOpportunityDisplay): UnifiedPosition => ({ id: y.yieldId as OpportunityId, assetId: y.yieldId as AssetId, underlyingAssetId: y.yieldId as AssetId, provider: y.providerName, apy: y.apy, fiatAmount: y.fiatAmount, icon: y.providerIcon, isYield: true, yieldId: y.yieldId, isReadOnly: true, opportunityName: undefined, // Add other required StakingEarnOpportunityType fields with defaults ...getDefaultStakingFields(), })
- Or extend
UnifiedPositionto be a discriminated union that properly represents both cases.
147-163: Consider removing debug logging before production.Similar to other files, the
console.debugwithJSON.stringifyshould be removed or gated for production builds.
272-295: Repeated type castingas StakingEarnOpportunityType & UnifiedPositionthroughout columns.The same cast is repeated in every cell renderer (lines 273, 302, 329, 347, 385). Consider extracting this to avoid repetition.
♻️ Extract casting to a helper or update RowProps
Option 1: Create a helper at the top of the columns definition:
const getOpp = (row: RowProps) => row.original as StakingEarnOpportunityType & UnifiedPositionOption 2: Update
RowPropstype definition to include the intersection type directly, though this may require more extensive changes.
📜 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.
📒 Files selected for processing (8)
src/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/DeFiEarn.tsxsrc/components/StakingVaults/PositionTable.tsxsrc/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.tssrc/react-queries/queries/yieldxyz/useYields.tssrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
src/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/components/StakingVaults/DeFiEarn.tsxsrc/react-queries/queries/yieldxyz/useYields.tssrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsxsrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
**/*.{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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
src/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/components/StakingVaults/DeFiEarn.tsxsrc/react-queries/queries/yieldxyz/useYields.tssrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsxsrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
**/*.{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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
src/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/components/StakingVaults/DeFiEarn.tsxsrc/react-queries/queries/yieldxyz/useYields.tssrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsxsrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
**/*.{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 useuseErrorToasthook for displaying errors with translated error messages and handle different error types appropriatelyUse PascalCase for React component names and match the component name to the file name
Files:
src/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsx
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
**/*.{jsx,tsx}: ALWAYS useuseMemofor expensive computations, object/array creations, and filtered data
ALWAYS useuseMemofor derived values and computed properties
ALWAYS useuseMemofor conditional values and simple transformations
ALWAYS useuseCallbackfor event handlers and functions passed as props
ALWAYS useuseCallbackfor any function that could be passed as a prop or dependency
ALWAYS include all dependencies inuseEffect,useMemo,useCallbackdependency arrays
NEVER use// eslint-disable-next-line react-hooks/exhaustive-depsunless 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 withmemofor performance optimization
Files:
src/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
Ensure TypeScript types are explicit and proper; avoid use of
anytype
Files:
src/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.tsx
src/state/slices/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/state/slices/**/*.ts: Migrations are required when changing persisted state structure (seesrc/state/migrations/)
Export selectors from slice using inlineselectorsproperty
Files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
src/state/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/state/**/*.{ts,tsx}: UsecreateDeepEqualOutputSelectorfrom@/state/selector-utilsfor deep equality checks
UsecreateCachedSelectorfromre-reselectfor parameterized selectors
Files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
🧠 Learnings (34)
📓 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: 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: 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: 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: 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-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/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/components/StakingVaults/DeFiEarn.tsxsrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
📚 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/components/StakingVaults/hooks/useYieldAsOpportunities.tssrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/PositionTable.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/StakingVaults/DeFiEarn.tsxsrc/components/StakingVaults/PositionTable.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/StakingVaults/DeFiEarn.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/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/PositionTable.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} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs
Applied to files:
src/components/StakingVaults/DeFiEarn.tsxsrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
📚 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/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/StakingVaults/DeFiEarn.tsxsrc/components/StakingVaults/PositionTable.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/components/StakingVaults/DeFiEarn.tsxsrc/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
📚 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 src/pages/Yields/components/YieldsList.tsx (and similar Yields UI components), gomesalexandre prefers omitting filters on mobile due to space constraints, even when filters could theoretically be implemented via a drawer or condensed UI. Mobile users can still navigate filtered views via URL parameters, but the filter UI itself is intentionally hidden on mobile.
Applied to files:
src/components/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/PositionTable.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/StakingVaults/DeFiEarn.tsxsrc/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/EarnDashboard/components/PositionDetails/PositionDetails.tsxsrc/components/StakingVaults/PositionTable.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/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/PositionTable.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/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsxsrc/components/StakingVaults/PositionTable.tsx
📚 Learning: 2025-08-05T22:41:35.473Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.
Applied to files:
src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.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/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx
📚 Learning: 2025-07-30T20:57:48.176Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10148
File: src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx:88-91
Timestamp: 2025-07-30T20:57:48.176Z
Learning: In src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx, NeOMakinG prefers keeping the hardcoded overscan value (40) over dynamic calculation based on viewport height, prioritizing code simplicity over precision when the current approach works effectively.
Applied to files:
src/components/StakingVaults/PositionTable.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 the translation hook: `useTranslate()` from `react-polyglot`
Applied to files:
src/components/StakingVaults/PositionTable.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 use `useErrorToast` hook for displaying errors with translated error messages and handle different error types appropriately
Applied to files:
src/components/StakingVaults/PositionTable.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/components/StakingVaults/PositionTable.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: 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`
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts expects a filter object with an assetId property, not a raw AssetId string. The selector signature is (state: ReduxState, filter) where filter should have an assetId property. This pattern is consistent across portfolio selectors that use selectAssetIdParamFromFilter. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts accepts a filter object with an assetId property, not a raw AssetId string. The selector signature is (state: ReduxState, filter) where filter is expected to have an assetId property. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.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: Feature flags are stored in Redux state under `preferences.featureFlags`
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts accepts a filter object with an assetId property (signature: (state, { assetId })), not a raw AssetId string. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.tssrc/react-queries/queries/yieldxyz/useAllYieldBalances.ts
📚 Learning: 2025-09-04T10:18:34.140Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10427
File: src/hooks/useActionCenterSubscribers/useSwapActionSubscriber.tsx:40-40
Timestamp: 2025-09-04T10:18:34.140Z
Learning: In the shapeshift/web codebase, src/state/slices/selectors.ts uses wildcard exports (`export * from './[sliceName]/selectors'`) to re-export all selectors from individual slice selector files, making them available through the barrel import. This means selectors like selectTxByFilter from txHistorySlice/selectors are properly accessible via '@/state/slices/selectors' even though they don't appear in explicit named exports.
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.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 src/state/slices/**/*.ts : Export selectors from slice using inline `selectors` property
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.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} : Use `useAppSelector` for Redux state
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
📚 Learning: 2025-08-10T21:09:25.643Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10215
File: src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts:65-67
Timestamp: 2025-08-10T21:09:25.643Z
Learning: In the MultiHopTrade components, `selectInputBuyAsset` and `selectInputSellAsset` selectors from `tradeInputSlice` always return defined values because they have default values in the initial state (BTC for buyAsset, ETH for sellAsset, with fallback to defaultAsset). Null checks for these assets are unnecessary when using these selectors.
Applied to files:
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
🧬 Code graph analysis (6)
src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (6)
src/state/slices/opportunitiesSlice/types.ts (1)
AggregatedOpportunitiesByAssetIdReturn(240-248)src/react-queries/queries/yieldxyz/useYields.ts (1)
useYields(59-190)src/react-queries/queries/yieldxyz/useAllYieldBalances.ts (1)
useAllYieldBalances(222-393)src/lib/yieldxyz/types.ts (1)
AugmentedYieldDto(366-378)packages/caip/src/assetId/assetId.ts (1)
fromAssetId(140-172)src/lib/yieldxyz/constants.ts (1)
DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_ID(101-104)
src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx (5)
src/state/slices/opportunitiesSlice/types.ts (1)
StakingEarnOpportunityType(215-218)src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (1)
YieldOpportunityDisplay(12-19)src/state/slices/opportunitiesSlice/utils/getMetadataForProvider.ts (1)
getMetadataForProvider(5-8)packages/caip/src/constants.ts (1)
thorchainAssetId(58-58)src/pages/RFOX/constants.ts (1)
RFOX_STAKING_ASSET_IDS(16-16)
src/components/EarnDashboard/components/PositionDetails/PositionDetails.tsx (3)
src/state/slices/opportunitiesSlice/types.ts (1)
AggregatedOpportunitiesByAssetIdReturn(240-248)src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (1)
YieldOpportunityDisplay(12-19)src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx (1)
StakingPositionsByProvider(98-438)
src/components/StakingVaults/PositionTable.tsx (6)
src/state/slices/opportunitiesSlice/types.ts (1)
AggregatedOpportunitiesByAssetIdReturn(240-248)src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (1)
YieldAggregatedOpportunity(21-25)src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx (1)
RowProps(55-55)src/state/store.ts (1)
useAppSelector(145-145)src/state/slices/assetsSlice/selectors.ts (1)
selectAssetsSortedByMarketCap(62-69)src/lib/utils/isEvmAddress.ts (1)
isEvmAddress(3-3)
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts (4)
src/state/slices/opportunitiesSlice/resolvers/types.ts (1)
OpportunityIdsResolverInput(35-37)src/state/slices/opportunitiesSlice/types.ts (1)
GetOpportunityIdsOutput(185-185)src/state/reducer.ts (1)
ReduxState(220-220)src/state/slices/preferencesSlice/selectors.ts (1)
selectFeatureFlag(12-16)
src/react-queries/queries/yieldxyz/useAllYieldBalances.ts (5)
src/lib/yieldxyz/constants.ts (1)
SUPPORTED_YIELD_NETWORKS(50-50)src/pages/Yields/YieldAccountContext.tsx (1)
useYieldAccount(48-58)src/state/store.ts (1)
useAppSelector(145-145)src/state/slices/portfolioSlice/selectors.ts (1)
selectAccountIdsByAccountNumberAndChainId(1094-1118)src/state/slices/common-selectors.ts (1)
selectEnabledWalletAccountIds(52-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: Install and Cache
🔇 Additional comments (31)
src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts (4)
27-27: LGTM!The import of
selectFeatureFlagis correct and aligns with the selector definition in the codebase.
35-37: LGTM!Clean early-exit pattern that disables Cosmos SDK staking opportunity resolution when the YieldXyz feature is enabled.
84-86: LGTM!Consistent early-exit pattern that returns an empty metadata result when YieldXyz is enabled.
180-185: LGTM!The
Promise.resolve()pattern is consistent with the existing return statements in this function (lines 190-192, 211, 213). The early-exit correctly returns empty user staking data when YieldXyz is enabled.src/components/StakingVaults/hooks/useYieldAsOpportunities.ts (4)
12-25: LGTM - Well-defined types for yield opportunity display.The type definitions clearly extend
AggregatedOpportunitiesByAssetIdReturnwith yield-specific fields (yieldOpportunities,searchable,isYield), enabling unified handling in downstream components.
38-63: LGTM - Clean initialization of aggregated opportunity structure.The aggregation logic correctly initializes each asset's opportunity record with all required fields from
AggregatedOpportunitiesByAssetIdReturnplus the yield-specific extensions.
71-83: Validator selection logic looks correct for Cosmos/Solana chains.The logic correctly uses
DEFAULT_NATIVE_VALIDATOR_BY_CHAIN_IDfor chains with native validators and falls back to the first validator for other chains. This aligns with the PR description stating it matches existing yield UI patterns.
147-152: LGTM - Correct memoization dependencies and return structure.The
useMemodependencies correctly includeyieldBalancesData?.aggregatedandyieldsData?.all. The loading state correctly combines both query states.src/components/StakingVaults/DeFiEarn.tsx (4)
27-31: LGTM - Props type correctly excludes internally-controlled properties.The
Omit<PositionTableProps, 'searchQuery' | 'data' | 'isLoading'>ensures consumers can't override the internally-managed state, which is the correct design for this data-aggregating component.
65-127: LGTM - Merging logic correctly combines yield and legacy positions.The merge logic:
- Seeds the map with yield opportunities when enabled
- Merges legacy positions, summing fiat amounts and selecting higher APY
- Combines opportunity arrays without duplicates
- Sorts by fiat amount descending
The use of
Mapensures O(1) lookups during the merge phase.
129-135: LGTM - Chain IDs correctly derived from both wallet and yield sources.The logic properly combines wallet-connected chain IDs with chain IDs extracted from yield opportunities, using
Setto deduplicate.
137-137: LGTM - Loading state correctly accounts for feature flag.The condition
isOpportunitiesLoading || (isYieldXyzEnabled && isYieldLoading)correctly only waits for yield loading when the feature is enabled.src/components/StakingVaults/PositionTable.tsx (6)
27-29: LGTM - UnifiedOpportunity type correctly composes base and yield types.Using
Partial<YieldAggregatedOpportunity>allows the type to represent both legacy positions (without yield fields) and yield opportunities (with all fields).
59-64: LGTM - Clean derivation of base and filtered positions.The chain filtering is correctly applied on top of the base positions, with proper memoization dependencies.
69-89: LGTM - Search filtering correctly handles EVM addresses and text search.The filter logic:
- Handles exact EVM address matching for contract searches
- Uses
matchSorterwithCONTAINSthreshold for text search- Includes the
searchablearray from yield opportunities in search keys
93-100: useEffect for processing rows is appropriate here.The
startTransitionwrapping ensures the filtering doesn't block UI updates. This pattern is appropriate for potentially expensive filtering operations.
139-145: Simplified APY cell always renders green tag.The APY column now unconditionally renders a green
Tagwith the APY value. Verify this is intentional - previously there may have been conditional coloring based on APY thresholds.
172-184: LGTM - renderSubComponent correctly passes yieldOpportunities.The spread of
originalprops plus explicityieldOpportunitiesensures all data flows toPositionDetailsfor expanded row rendering.src/components/EarnDashboard/components/PositionDetails/PositionDetails.tsx (3)
9-12: LGTM - Props type correctly extended with optional yieldOpportunities.The type extension allows backward compatibility while enabling yield data flow.
26-28: LGTM - Guard correctly handles both staking and yield positions.The
hasPositionscheck ensures the component renders only when there's actual data to display, covering both legacy staking and new yield opportunities.
32-36: LGTM - Clean prop threading to StakingPositionsByProvider.The component correctly passes all required props including the new
yieldOpportunities.src/components/EarnDashboard/components/PositionDetails/StakingPositionsByProvider.tsx (6)
42-45: LGTM - UnifiedPosition extends StakingEarnOpportunityType with yield flags.The type extension cleanly adds optional yield-specific fields while maintaining compatibility with legacy staking positions.
169-175: LGTM - Yield-specific navigation correctly routes to /yields/{yieldId}.The early return for yield positions ensures proper routing without triggering legacy staking logic.
304-311: LGTM - Yield rows correctly skip reward calculation.Setting
fiatRewardsAmountto 0 for yield rows prevents attempting to calculate rewards from undefinedrewardAssetIdsandrewardsCryptoBaseUnit.
330-333: LGTM - RFOX detection correctly excludes yield rows.The condition
!opp.isYield && RFOX_STAKING_ASSET_IDS.includes(opp.underlyingAssetId)ensures yield positions don't incorrectly trigger RFOX-specific APY rendering.
350-350: LGTM - Yield rows correctly show dash for claimable rewards.Since yield positions don't have claimable rewards in this context, returning early with a dash is the correct behavior.
388-391: LGTM - Translation logic correctly handles yield vs legacy positions.The ternary correctly returns 'common.view' for yield positions, 'common.manage' for editable positions, and conditionally 'common.view' for read-only positions with URLs.
src/react-queries/queries/yieldxyz/useYields.ts (1)
53-57: Clear params contract.Nice, explicit params type for the hook inputs.
src/react-queries/queries/yieldxyz/useAllYieldBalances.ts (3)
20-23: Verify “all accounts” behavior isn’t still scoped toaccountNumber.
targetAccountIdsprefersaccountIdsForAccountNumberbeforeenabledWalletAccountIds. If the “all accounts” view still supplies a definedaccountNumber(e.g.,0), this will keep results scoped to that account number and exclude other enabled accounts. Please confirm the Yield account context setsaccountNumbertoundefined(or adjust the priority) when the UI intends to show all enabled accounts.Also applies to: 227-245
26-30: Nice addition: opt-in query gating viaenabled.The new
enabledoption andenabled: isEnabledwiring give callers explicit control over fetches without altering existing defaults. Looks good.Also applies to: 223-225, 337-337
248-263: Query payloads now correctly derive fromtargetAccountIds.Using
targetAccountIdsin the guard and dependency array keeps requests aligned with account selection and avoids stale account scoping.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Prevents users from switching accounts mid-transaction which caused an awkward state with disabled buttons. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Went with a naive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/pages/Yields/components/YieldEnterModal.tsx (1)
299-303: UseAccountIdin the account selector handler.The
selectedAccountIdstate is explicitly typed asAccountId | undefined(line ~270), but the handler parameter acceptsstringon line 299, which breaks nominal typing. TheAccountSelectorcomponent also expectsonChange: (accountId: AccountId) => void, so the parameter type must beAccountIdto match both the state type and component expectations.🔧 Proposed fix
- const handleAccountChange = useCallback((newAccountId: string) => { + const handleAccountChange = useCallback((newAccountId: AccountId) => { setSelectedAccountId(newAccountId) setCryptoAmount('') setSelectedPercent(null) }, [])src/pages/Yields/components/YieldForm.tsx (1)
188-203: YieldForm defaults to account 0 but should match YieldEnterModal's fallback strategy.
derivedAccountNumberfalls back to0when noaccountNumberoraccountIdPropis provided, but YieldEnterModal usesundefinedinstead. This causes YieldForm to always attempt account 0 for the chain, even if it's not in the filteredaccountIdslist or lacks the asset balance. Unlike YieldEnterModal which falls back toaccountIds[0](guaranteed to have the asset), YieldForm can end up withaccountId = undefined. Consider matching YieldEnterModal's pattern: defaultderivedAccountNumbertoundefinedand add a secondary fallback toaccountIds[0].
📜 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.
📒 Files selected for processing (2)
src/pages/Yields/components/YieldEnterModal.tsxsrc/pages/Yields/components/YieldForm.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 runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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 useuseErrorToasthook for displaying errors with translated error messages and handle different error types appropriatelyUse PascalCase for React component names and match the component name to the file name
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
**/*.{jsx,tsx}: ALWAYS useuseMemofor expensive computations, object/array creations, and filtered data
ALWAYS useuseMemofor derived values and computed properties
ALWAYS useuseMemofor conditional values and simple transformations
ALWAYS useuseCallbackfor event handlers and functions passed as props
ALWAYS useuseCallbackfor any function that could be passed as a prop or dependency
ALWAYS include all dependencies inuseEffect,useMemo,useCallbackdependency arrays
NEVER use// eslint-disable-next-line react-hooks/exhaustive-depsunless 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 withmemofor performance optimization
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)
Ensure TypeScript types are explicit and proper; avoid use of
anytype
Files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
🧠 Learnings (29)
📓 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: 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: 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: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.
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: 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.
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:0-0
Timestamp: 2025-09-12T11:56:19.437Z
Learning: gomesalexandre rejected verbose try/catch error handling for address validation in Tenderly integration (PR `#10461`), calling the approach "ugly" but still implemented safety measures in commit ad7e424b89, preferring cleaner safety implementations over defensive programming patterns.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10566
File: src/hooks/useLedgerAccountGuard/useLedgerAccountGuard.tsx:4-4
Timestamp: 2025-09-23T10:36:13.916Z
Learning: gomesalexandre dismisses suggestions to expand PR scope beyond the current migration when the PR is already systematically implementing the desired pattern (like KeyManager.Ledger migration) within focused boundaries, preferring to keep scope contained rather than doing comprehensive codebase-wide cleanups.
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: 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: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/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/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 Chakra UI components and conventions
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-05T22:41:35.473Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-22T13:00:23.679Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/Fox/FoxEcosystemPage.tsx:28-44
Timestamp: 2025-08-22T13:00:23.679Z
Learning: In the shapeshift/web codebase, explicit React component type annotations (like React.FC) are not required or preferred. The team doesn't prioritize adding these type annotations to functional components.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/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} : 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/YieldForm.tsx
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts accepts a filter object with an assetId property (signature: (state, { assetId })), not a raw AssetId string. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts expects a filter object with an assetId property, not a raw AssetId string. The selector signature is (state: ReduxState, filter) where filter should have an assetId property. This pattern is consistent across portfolio selectors that use selectAssetIdParamFromFilter. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts accepts a filter object with an assetId property, not a raw AssetId string. The selector signature is (state: ReduxState, filter) where filter is expected to have an assetId property. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-09-04T10:18:34.140Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10427
File: src/hooks/useActionCenterSubscribers/useSwapActionSubscriber.tsx:40-40
Timestamp: 2025-09-04T10:18:34.140Z
Learning: In the shapeshift/web codebase, src/state/slices/selectors.ts uses wildcard exports (`export * from './[sliceName]/selectors'`) to re-export all selectors from individual slice selector files, making them available through the barrel import. This means selectors like selectTxByFilter from txHistorySlice/selectors are properly accessible via '@/state/slices/selectors' even though they don't appear in explicit named exports.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/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 src/state/slices/**/*.ts : Export selectors from slice using inline `selectors` property
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/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: Portfolio state is filtered by active `walletId`
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-08-21T22:16:55.203Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useFetchBasePortfolio.ts:33-35
Timestamp: 2025-08-21T22:16:55.203Z
Learning: In the ShapeShift web codebase Base portfolio management hack, the accountsById[accountId] check in upsertBasePortfolio serves as a security safeguard to ensure only user-associated accounts get balance updates, not just an existence check - this boundary should be maintained even during degraded Base state.
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/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 `useAppSelector` for Redux state
Applied to files:
src/pages/Yields/components/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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/YieldForm.tsxsrc/pages/Yields/components/YieldEnterModal.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-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/YieldEnterModal.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
📚 Learning: 2025-08-10T21:09:25.643Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10215
File: src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts:65-67
Timestamp: 2025-08-10T21:09:25.643Z
Learning: In the MultiHopTrade components, `selectInputBuyAsset` and `selectInputSellAsset` selectors from `tradeInputSlice` always return defined values because they have default values in the initial state (BTC for buyAsset, ETH for sellAsset, with fallback to defaultAsset). Null checks for these assets are unnecessary when using these selectors.
Applied to files:
src/pages/Yields/components/YieldEnterModal.tsx
📚 Learning: 2025-09-02T00:02:44.889Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10380
File: src/components/AssetSearch/components/GroupedAssetRow.tsx:116-0
Timestamp: 2025-09-02T00:02:44.889Z
Learning: premiumjibles prefers avoiding store.getState() calls in favor of useAppSelector where reactivity is needed, to prevent accidentally breaking reactive updates in components.
Applied to files:
src/pages/Yields/components/YieldEnterModal.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/YieldEnterModal.tsx
🧬 Code graph analysis (2)
src/pages/Yields/components/YieldForm.tsx (2)
src/state/store.ts (1)
useAppSelector(145-145)src/state/slices/portfolioSlice/selectors.ts (2)
selectAccountNumberByAccountId(135-138)selectAccountIdByAccountNumberAndChainId(1071-1092)
src/pages/Yields/components/YieldEnterModal.tsx (2)
src/state/store.ts (1)
useAppSelector(145-145)src/state/slices/portfolioSlice/selectors.ts (2)
selectAccountNumberByAccountId(135-138)selectAccountIdByAccountNumberAndChainId(1071-1092)
⏰ 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 (4)
src/pages/Yields/components/YieldEnterModal.tsx (2)
54-159: AccountId-aware default selection looks solid.The accountId prop, derived account lookup, and fallback sequencing are coherent and align well with multi-account behavior.
587-588: Good: success routing + mid-transaction guard.Passing
accountIdintoYieldSuccessand disabling account switching while submitting match the intended UX safeguard.Also applies to: 632-632
src/pages/Yields/components/YieldForm.tsx (2)
2-164: AccountId plumbing and handler typing look consistent.Prop typing, state initialization, and the AccountId-typed handler are cohesive.
Also applies to: 380-384
729-730: Success view and selector disablement are aligned with the flow.Passing
accountIdintoYieldSuccessand preventing account changes mid-submit is a clean, safe addition.Also applies to: 747-747
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
Description
Does what it says on the box i.e:
Issue (if applicable)
Risk
Low - behind
YieldMultiAccountfeature flagNone - UI only changes for yield display and account selection
Testing
Engineering
Note: test with flag on - assume this will ship with it
Operations
Screenshots (if applicable)
https://jam.dev/c/fbf0f785-b277-424e-8f07-20d4ce900339
Summary by CodeRabbit
New Features
UI Improvements
Translations
Tests
✏️ Tip: You can customize this high-level summary in your review settings.