Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Nov 24, 2025

Description

Makes GridPlus actually usable by not spewing random requests to gridpl.us in network tab during normal app usage:

  • swapper approval steps
  • CoW message signing
  • swapper UTXO Txs
  • swapper final quote fees estimation polling
  • UTXO sends
  • Solana sends
  • FOX Farming withdraws, claims
  • Trade quote/rate input

Issue (if applicable)

Risk

High Risk PRs Require 2 approvals

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

Testing

  • Connect a GridPlus and import accounts
  • Ensure swapper approvals do not trigger requests to gridpl.us in network tab
  • Ensure CoW message signing in swapper/limit orders do not trigger requests to gridpl.us
  • When selling BTC or other UTXOs in swapper, ensure you do not see requests at interval at final quote time (fees polling)
  • When sending UTXOs or Solana, ensure that you do not see gridpl.us requests
  • When withdrawing or claiming from FOX farming, you don't see gridpl.us requests
  • When typing amounts in swapper, ensure no gridpl.us requests during rate updates
  • When doing an EVM send with Gridplus, no address request is made
  • When doing a Solana send with Gridplus, no address request is made

Engineering

  • Connect GridPlus wallet and test all flows above - network tab should show significantly fewer requests to gridpl.us
  • Generally speaking, no need to test all flows in super details, app should just feel usable now with Gridplus without slowness, swapper in particular

Disregard the below, published and bumped in web origin/develop already!

Note: for Solana and EVM chains, there's still an inner call to getAddress() in hdwallet land when signing, that's going to be tackled separately and will require an hdwallet bump.

Operations

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

Still under flag, but if you have a Gridplus to test this, it should now feel usable in app!

Screenshots (no Jam/XHRs for deviceId privacy)

gridplus.derivation.mov

Summary by CodeRabbit

  • New Features

    • Added GridPlus hardware wallet support across trading, swapping, and DeFi farming—GridPlus devices can now be used alongside Ledger and Trezor for transactions and quotes.
  • Chores

    • Updated npm authentication configuration format in project settings.

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

Adds GridPlus to skipDeviceDerivation check for all chain namespaces
(EVM, UTXO, Cosmos, Solana) in fee estimation polling.

This prevents network requests to GridPlus device every 15 seconds during
trade confirmation, significantly improving quote screen performance.
Adds GridPlus to skipDeviceDerivation check when fetching trade rates.

This prevents network requests to GridPlus device during trade input amount
changes and rate polling, significantly improving swapper input UX.
Adds GridPlus to skipDeviceDerivation check in both trade approval hooks.

This prevents network requests to GridPlus device when checking allowances
and building approval transactions for swaps and limit orders.
Adds GridPlus to skipDeviceDerivation check for all chain namespaces
during trade execution (CoW, EVM, UTXO, Cosmos, Solana).

This prevents network requests to GridPlus device when executing swaps,
significantly improving swap UX and reducing latency.
Adds GridPlus to skipDeviceDerivation check for FOX farming unstake/withdraw
and claim operations.

This prevents network requests to GridPlus device when building FOX farming
transactions, improving DeFi operation UX.
Adds GridPlus to pubKey checks for UTXO and Solana send flows.

This prevents network requests to GridPlus device when building send
transactions and getting sender addresses, improving send flow UX.

Also removes debug console.log from UTXO send flow.
Adds GridPlus to skipDeviceDerivation check when fetching trade quotes.

Also fixes dependency arrays in FOX farming hooks to include skipDeviceDerivation.
@gomesalexandre gomesalexandre requested a review from a team as a code owner November 24, 2025 14:21
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Warning

Rate limit exceeded

@gomesalexandre has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 15 minutes and 27 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7b2d821 and 33750b2.

📒 Files selected for processing (1)
  • src/components/Modals/Send/utils.ts (8 hunks)
📝 Walkthrough

Walkthrough

Adds GridPlus hardware wallet support by introducing a unified skipDeviceDerivation flag (covering Ledger, Trezor, GridPlus) and replacing per-wallet pubKey derivation checks with this flag across send, trade, allowance, fee, and farming flows.

Changes

Cohort / File(s) Summary
Configuration
\.yarnrc.yml``
Quoted the npmAuthToken value to "${NPM_AUTH-fallback}" (was unquoted).
Send Modal
src/components/Modals/Send/utils.ts
Import isGridPlus; introduce skipDeviceDerivation for Ledger/Trezor/GridPlus and use it to gate pubKey/account derivation across UTXO, Solana, and address-getting flows.
Trade Quotes & Rate Input
src/components/MultiHopTrade/hooks/.../useGetTradeQuotes.tsx, src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
Import isGridPlus; compute pubKey via skipDeviceDerivation (Ledger/Trezor/GridPlus) and use it in trade quote/rate input construction and hook dependencies.
Allowance Approval (LimitOrderV2 & TradeConfirm)
src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx, src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
Extend device-derivation skip logic to include GridPlus alongside Trezor when deciding whether to derive/pass a pubKey for approvals.
Trade Execution
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
Add isGridPlus and skipDeviceDerivation; thread a derived pubKey through CowSwap and non-CowSwap paths and across EVM/UTXO/Cosmos/Solana getAddress/getPublicKey/xpub flows.
Trade Network Fee
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
Use skipDeviceDerivation (Ledger/Trezor/GridPlus) to control xpub/pubKey inclusion and address derivation across chain namespaces.
DeFi Farming (Fox Farming)
src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
Import isGridPlus; replace isTrezor gating with skipDeviceDerivation for stake/unstake/claimRewards pubKey usage and update dependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Extra attention areas:
    • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx — complex branching (CowSwap vs non-CowSwap) and multiple chain adapters.
    • Correctness of skipDeviceDerivation detection for Ledger/Trezor/GridPlus and its propagation into memoized dependency arrays.
    • Ensure pubKey/xpub usage is consistent and secure across UTXO, EVM, Cosmos, Solana, and farming flows.

Possibly related PRs

Suggested labels

high risk

Suggested reviewers

  • NeOMakinG
  • premiumjibles

Poem

🐰 I hopped in with a tiny cheer,
GridPlus, Ledger, Trezor near,
One flag to skip the derivation song,
Pubkeys threaded clean and strong,
Hoppy trades — I hum along! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes a .yarnrc.yml configuration change that is unrelated to the GridPlus derivation skip feature mentioned in the linked issue. Remove or document the .yarnrc.yml change, or move it to a separate PR if it addresses a different concern.
Title check ❓ Inconclusive The PR title 'feat: many many gridplus skip derivation bits' is vague and uses non-descriptive informal language ('many many', 'bits') that obscures the actual change. Replace with a more specific title like 'feat: skip GridPlus device derivation across multiple flows' to clearly convey the main objective.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR substantially addresses the linked issue #11146 by implementing GridPlus skip derivation across multiple flows, though it focuses on skipping derivations rather than batching as originally investigated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

❤️ Share

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

@gomesalexandre gomesalexandre changed the title feat: many many trezor gridplus skip derivation bits feat: many many gridplus skip derivation bits Nov 24, 2025
Base automatically changed from feat_trezor_approvals to develop November 25, 2025 14:15
Resolved merge conflicts by preserving GridPlus skip derivation logic
alongside Trezor. All conflicts resolved to support both wallet types:
- isGridPlus(wallet) || isTrezor(wallet) for skipDeviceDerivation checks
- Removed debug console.log from develop branch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts (1)

84-89: Remove unnecessary eslint-disable comment.

The dependency array [wallet, sellAccountId] correctly captures all reactive values used in the useMemo. The isLedger, isTrezor, isGridPlus, and fromAccountId are stable function references that don't need to be dependencies. The eslint-disable appears unnecessary.

   const pubKey = useMemo(() => {
     const skipDeviceDerivation =
       wallet && (isLedger(wallet) || isTrezor(wallet) || isGridPlus(wallet))
     return skipDeviceDerivation && sellAccountId ? fromAccountId(sellAccountId).account : undefined
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [wallet, sellAccountId])
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 460c687 and a047b1d.

📒 Files selected for processing (9)
  • .yarnrc.yml (1 hunks)
  • src/components/Modals/Send/utils.ts (5 hunks)
  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx (2 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx (2 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (6 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (6 hunks)
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx (3 hunks)
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts (3 hunks)
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts (6 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{tsx,jsx}

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

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

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{js,jsx,ts,tsx}

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

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{jsx,tsx}

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

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.tsx

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

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

Files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
🧠 Learnings (43)
📓 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: 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: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.699Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
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: gomesalexandre
Repo: shapeshift/web PR: 10232
File: packages/unchained-client/openapitools.json:61-61
Timestamp: 2025-08-08T10:23:16.843Z
Learning: In shapeshift/web, for temporary “monkey patch” PRs (e.g., packages/unchained-client/openapitools.json using jsDelivr CDN refs like cosmos/mayachain), gomesalexandre is fine with branch-based URLs and does not want SHA pinning. Treat this as a scoped exception to their general preference for pinned dependencies/refs.
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Branch naming: Use descriptive names (e.g., `feat_gridplus`, `fix_wallet_connect`)
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: 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: 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: 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: 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: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-09-04T12:16:47.748Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10430
File: src/components/Layout/Header/NavBar/PopoverWallet.tsx:72-94
Timestamp: 2025-09-04T12:16:47.748Z
Learning: gomesalexandre declined to add error boundaries to the PopoverWallet component in src/components/Layout/Header/NavBar/PopoverWallet.tsx, stating he didn't touch this component and preferring not to expand the scope of the PR with error boundary additions.

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-19T22:20:25.661Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10767
File: package.json:324-324
Timestamp: 2025-11-19T22:20:25.661Z
Learning: In shapeshift/web package.json, the resolution "gridplus-sdk/bs58check": "2.1.2" is intentional and must not be removed. It forces gridplus-sdk's transitive bs58check dependency from 4.0.0 down to 2.1.2 because bs58check 4.0.0 breaks legacy address validation (due to bs58 v6.0.0 and noble/hash vs 2.1.2's bs58 v4.0.0 and create-hash).

Applied to files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-05T23:37:30.632Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10912
File: src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx:290-290
Timestamp: 2025-11-05T23:37:30.632Z
Learning: In the ShapeShift web codebase, `isMobile` imported from '@/lib/globals' is a module-level constant (defined as `export const isMobile = Boolean(window?.isShapeShiftMobile)`) that is evaluated once at module load time. It is a stable reference that does not need to be included in useCallback/useMemo/useEffect dependency arrays.

Applied to files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.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: Portfolio state is filtered by active `walletId`

Applied to files:

  • src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.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: Each wallet has unique `walletId` (e.g., `metamask:0x123`, `ledger:ABC`)

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-11T09:46:41.060Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10219
File: src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx:167-172
Timestamp: 2025-08-11T09:46:41.060Z
Learning: In the shapeshift/web repository, the display cache logic for trade quotes (using `selectUserAvailableTradeQuotes` and `selectUserUnavailableTradeQuotes`) is intentionally kept the same between `TradeInput.tsx` and `TradeQuotes.tsx` components. The `hasQuotes` computation in `TradeInput.tsx` uses these display cache selectors by design, matching the pattern used in `TradeQuotes.tsx`.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.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/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

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

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-09-18T23:47:14.810Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10566
File: src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts:55-66
Timestamp: 2025-09-18T23:47:14.810Z
Learning: In the useWalletSupportsChain architecture, checkWalletHasRuntimeSupport() determines if the app has runtime capability to interact with a chain type (not actual signing capabilities), while walletSupportsChain() does the actual capabilities detection by checking account IDs. For Ledger read-only mode, checkWalletHasRuntimeSupport should return true since the app can display balances/addresses, with KeyManager being the source of truth rather than wallet instance.

Applied to files:

  • src/components/Modals/Send/utils.ts
📚 Learning: 2025-09-16T08:47:31.440Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10528
File: src/plugins/walletConnectToDapps/utils/createApprovalNamespaces.ts:39-47
Timestamp: 2025-09-16T08:47:31.440Z
Learning: In WalletConnect dApps createApprovalNamespaces logic, required namespaces have different semantics than optional namespaces. Required namespaces are validated upfront in the UI - users cannot proceed without accounts for all required chains, and required chains are always selected and unselectable. Therefore, additional filtering by selectedChainIds is unnecessary for required namespaces since the validation flow guarantees they will be supported and selected.

Applied to files:

  • src/components/Modals/Send/utils.ts
📚 Learning: 2025-09-12T10:15:10.389Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:133-137
Timestamp: 2025-09-12T10:15:10.389Z
Learning: gomesalexandre has identified that EIP-712 domain chainId should be preferred over request context chainId for accuracy in WalletConnect dApps structured signing flows. The domain chainId from the parsed message is more specific and accurate than the general request context, especially for asset resolution and network-specific operations.

Applied to files:

  • src/components/Modals/Send/utils.ts
📚 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 **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/hooks/useGetTradeRateInput.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: Uses Redux Toolkit with createSlice

Applied to files:

  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
📚 Learning: 2025-08-04T16:02:27.360Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T16:02:27.360Z
Learning: In multi-hop swap transactions, last hop sell transactions might not be detected by the swapper (unlike buy transactions which are always known immediately). The conditional stepSource logic for last hop buy transactions (`isLastHopSellTxSeen ? stepSource : undefined`) serves as defensive programming for future multi-hop support with intermediate chains, even though multi-hop functionality is not currently supported in production.

Applied to files:

  • src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
📚 Learning: 2025-10-13T11:55:57.439Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10751
File: src/Routes/RoutesCommon.tsx:190-190
Timestamp: 2025-10-13T11:55:57.439Z
Learning: In the shapeshift/web codebase, there are multiple independent claim systems: Arbitrum bridge claims (removed in PR #10751), RFOX claims (in src/pages/RFOX/components/Claim/), and TCY claims (in src/pages/TCY/). Each has its own routes, components, and logic. When reviewing claim-related changes, distinguish which system is being modified and avoid suggesting changes to unrelated claim systems.

Applied to files:

  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
📚 Learning: 2025-11-20T12:00:45.005Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11078
File: src/setupVitest.ts:11-15
Timestamp: 2025-11-20T12:00:45.005Z
Learning: In shapeshift/web, src/setupVitest.ts must redirect 'ethers' to 'ethers5' for shapeshiftoss/hdwallet-trezor (and -trezor-connect), same as ledger and shapeshift-multichain. Removing 'trezor' from the regex causes CI/Vitest failures due to ethers v6 vs v5 API differences.

Applied to files:

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

Applied to files:

  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
📚 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/MultiHopTrade/hooks/useGetTradeRateInput.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-10-15T15:57:39.956Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-29T07:07:49.332Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10386
File: src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx:272-294
Timestamp: 2025-08-29T07:07:49.332Z
Learning: In UTXO sell address verification flow in VerifyAddresses.tsx, the user wants address verification to be marked as "verified/complete" before starting the change address fetch, not after. The verification step and change address fetch should be treated as separate sequential operations in the UI flow.

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-12T13:01:06.086Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts:25-38
Timestamp: 2025-11-12T13:01:06.086Z
Learning: In the swapper architecture (packages/swapper), input validation for sell amounts (e.g., checking sellAmount > 0) is handled by the application layer before reaching individual swapper implementations. Swapper methods like getTradeRate and getTradeQuote can assume inputs have already been validated upstream, so defensive guards for basic input validation (amount > 0, valid addresses, etc.) are unnecessary at the swapper layer.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-04T15:36:25.122Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T15:36:25.122Z
Learning: In swap transaction handling, buy transaction hashes should always use the swapper's explorer (stepSource) because they are known by the swapper immediately upon swap execution. The conditional logic for using default explorers applies primarily to sell transactions which need to be detected/indexed by external systems like Thorchain or ViewBlock.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-26T19:04:38.672Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10369
File: packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts:167-176
Timestamp: 2025-08-26T19:04:38.672Z
Learning: In packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts, when processing assets from data.assets.reduce(), the team prefers using empty catch blocks to gracefully skip any assets that fail processing, rather than specific error type handling, to avoid useless noise and ensure robust asset filtering.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
🧬 Code graph analysis (1)
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (1)
src/lib/utils/evm/index.ts (1)
  • assertGetEvmChainAdapter (187-196)
⏰ 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 (8)
.yarnrc.yml (1)

3-3: The quoted environment variable will be properly expanded by Yarn.

Yarn (v3.5.0, as specified in this repository) expands environment variables in .yarnrc.yml regardless of whether they are quoted or unquoted. The syntax ${NPM_AUTH-fallback} will correctly expand the NPM_AUTH environment variable if present, or fall back to the literal string "fallback" if not. The quoting does not prevent this expansion.

Additionally, this repository uses only the public npm registry (https://registry.npmjs.org) with no scoped or private registries configured, so the npmAuthToken setting is not actively used in the CI/CD pipeline. The workflows run yarn install --immutable successfully without any npm authentication environment variables being set.

src/components/MultiHopTrade/components/LimitOrderV2/hooks/useAllowanceApproval.tsx (1)

3-3: GridPlus added to skip derivation logic.

The change correctly extends the skipDeviceDerivation pattern to include GridPlus alongside Trezor. Note that this file excludes isLedger unlike some other files in this PR (e.g., useGetTradeQuotes, useGetTradeRateInput), which appears intentional since both allowance approval hooks follow the same pattern.

Also applies to: 92-96

src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx (1)

3-3: Consistent GridPlus integration with LimitOrderV2 allowance approval.

The change mirrors the pattern in the LimitOrderV2 version, correctly adding GridPlus to the skip derivation logic alongside Trezor for allowance approvals.

Also applies to: 82-86

src/components/MultiHopTrade/hooks/useGetTradeQuotes/useGetTradeQuotes.tsx (1)

187-208: GridPlus correctly integrated with full hardware wallet support.

The skipDeviceDerivation logic now covers all three hardware wallet types (Ledger, Trezor, GridPlus), which is appropriate for the trade quote input path. The pubKey derivation conditional follows the established pattern.

src/components/Modals/Send/utils.ts (1)

20-20: Comprehensive GridPlus integration across all send paths.

The skipDeviceDerivation pattern is correctly applied to:

  • UTXO transaction building (line 210-212)
  • Solana send transactions (line 281)
  • Final address derivation (line 306)

The maybeFetchChangeAddress function (line 374) appropriately remains Ledger-only since change address pre-fetching is specific to Ledger hardware wallet behavior.

Also applies to: 145-145, 210-212, 281-281, 306-306

src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts (1)

66-67: GridPlus integration for FOX Farming operations.

The skipDeviceDerivation pattern is correctly applied to both unstake and claimRewards operations. The dependency arrays properly include skipDeviceDerivation to ensure callbacks update when the wallet type changes.

Note: The stake callback (lines 68-110) and approve callback (lines 272-298) don't include pubKey - this appears to be a pre-existing pattern where only withdraw/claim operations required the pubKey optimization.

Also applies to: 131-134, 158-158, 317-319, 338-338

src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (1)

294-296: Comprehensive GridPlus support across all chain namespaces in trade execution.

The implementation correctly:

  1. Skips expensive getPublicKey calls for UTXO chains when skipDeviceDerivation is true (lines 380-382)
  2. Passes pubKey to getAddress calls across EVM, UTXO, CosmosSdk, and Solana paths
  3. Maintains the existing pattern where pubKey is only used when skipDeviceDerivation evaluates to true

This aligns with the PR objective of preventing excessive GridPlus network requests during trade execution.

Also applies to: 302-302, 347-347, 380-388, 412-416, 446-446

src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (1)

3-3: Unified skipDeviceDerivation for Ledger/Trezor/GridPlus looks correct

The new isGridPlus import and skipDeviceDerivation flag are wired consistently across EVM, UTXO, Cosmos, and Solana branches: when the wallet is Ledger/Trezor/GridPlus, you reuse the CAIP account’s account field for pubKey/xpub and pass it through to getAddress/getPublicKey, while preserving prior behavior for other wallets. This matches the existing Ledger/Trezor pattern and should safely avoid extra GridPlus derivation calls without changing behavior elsewhere.

Given the high‑risk nature of the change, please double‑check the listed GridPlus flows (UTXO sends/sells, Solana sends, swapper fee estimation) in the browser network tab to confirm there are no unexpected gridpl.us derivation requests.

Also applies to: 95-97, 105-105, 128-136, 160-164, 181-186

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (1)

472-497: Based on my verification, I've found that the review comment's concern is valid but partially incorrect about the pattern. The Tron adapter does support the pubKey parameter, and there's an actual inconsistency in how it's handled across the codebase. Let me generate the rewritten review comment:


Add device derivation optimization to Tron path for consistency with fee calculation.

The Tron execution path (line 474) doesn't pass the pubKey parameter for device derivation, while useTradeNetworkFeeCryptoBaseUnit.tsx already does this for the same Tron case with the pattern ...(isLedger(wallet) || isTrezor(wallet) ? { pubKey } : {}). This causes unnecessary device derivation calls for Ledger and Trezor wallets during trade execution.

Update line 474 to match the pattern used in useTradeNetworkFeeCryptoBaseUnit.tsx:

const from = await adapter.getAddress({
  accountNumber,
  wallet,
  ...(isLedger(wallet) || isTrezor(wallet) ? { pubKey } : {}),
})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a047b1d and 7b2d821.

📒 Files selected for processing (4)
  • src/components/Modals/Send/utils.ts (5 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (6 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (6 hunks)
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/Modals/Send/utils.ts
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{tsx,jsx}

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

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

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{js,jsx,ts,tsx}

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

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.{jsx,tsx}

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

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
**/*.tsx

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

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

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
🧠 Learnings (27)
📓 Common learnings
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: 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: 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: 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: 10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.699Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
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: gomesalexandre
Repo: shapeshift/web PR: 10232
File: packages/unchained-client/openapitools.json:61-61
Timestamp: 2025-08-08T10:23:16.843Z
Learning: In shapeshift/web, for temporary “monkey patch” PRs (e.g., packages/unchained-client/openapitools.json using jsDelivr CDN refs like cosmos/mayachain), gomesalexandre is fine with branch-based URLs and does not want SHA pinning. Treat this as a scoped exception to their general preference for pinned dependencies/refs.
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:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.
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-08-08T11:40:55.734Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx:41-41
Timestamp: 2025-08-08T11:40:55.734Z
Learning: In MultiHopTrade confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx and related hooks), there is only one active trade per flow. Because of this, persistent (module/Redux) dedupe for QuotesReceived in useTrackTradeQuotes is not necessary; the existing ref-based dedupe is acceptable.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-04T16:02:27.360Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T16:02:27.360Z
Learning: In multi-hop swap transactions, last hop sell transactions might not be detected by the swapper (unlike buy transactions which are always known immediately). The conditional stepSource logic for last hop buy transactions (`isLastHopSellTxSeen ? stepSource : undefined`) serves as defensive programming for future multi-hop support with intermediate chains, even though multi-hop functionality is not currently supported in production.

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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 **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-19T22:20:25.661Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10767
File: package.json:324-324
Timestamp: 2025-11-19T22:20:25.661Z
Learning: In shapeshift/web package.json, the resolution "gridplus-sdk/bs58check": "2.1.2" is intentional and must not be removed. It forces gridplus-sdk's transitive bs58check dependency from 4.0.0 down to 2.1.2 because bs58check 4.0.0 breaks legacy address validation (due to bs58 v6.0.0 and noble/hash vs 2.1.2's bs58 v4.0.0 and create-hash).

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-11-12T13:01:06.086Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts:25-38
Timestamp: 2025-11-12T13:01:06.086Z
Learning: In the swapper architecture (packages/swapper), input validation for sell amounts (e.g., checking sellAmount > 0) is handled by the application layer before reaching individual swapper implementations. Swapper methods like getTradeRate and getTradeQuote can assume inputs have already been validated upstream, so defensive guards for basic input validation (amount > 0, valid addresses, etc.) are unnecessary at the swapper layer.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-04T15:36:25.122Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T15:36:25.122Z
Learning: In swap transaction handling, buy transaction hashes should always use the swapper's explorer (stepSource) because they are known by the swapper immediately upon swap execution. The conditional logic for using default explorers applies primarily to sell transactions which need to be detected/indexed by external systems like Thorchain or ViewBlock.

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.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: Each wallet has unique `walletId` (e.g., `metamask:0x123`, `ledger:ABC`)

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-29T07:07:49.332Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10386
File: src/components/MultiHopTrade/components/VerifyAddresses/VerifyAddresses.tsx:272-294
Timestamp: 2025-08-29T07:07:49.332Z
Learning: In UTXO sell address verification flow in VerifyAddresses.tsx, the user wants address verification to be marked as "verified/complete" before starting the change address fetch, not after. The verification step and change address fetch should be treated as separate sequential operations in the UI flow.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
📚 Learning: 2025-08-26T19:04:38.672Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10369
File: packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts:167-176
Timestamp: 2025-08-26T19:04:38.672Z
Learning: In packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts, when processing assets from data.assets.reduce(), the team prefers using empty catch blocks to gracefully skip any assets that fail processing, rather than specific error type handling, to avoid useless noise and ensure robust asset filtering.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx
🧬 Code graph analysis (1)
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (1)
src/lib/utils/evm/index.ts (1)
  • assertGetEvmChainAdapter (187-196)
⏰ 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 (1)
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx (1)

6-6: LGTM!

The GridPlus import is correctly added and necessary for the skipDeviceDerivation logic.

@gomesalexandre
Copy link
Contributor Author

Ditto yeeting as this is isolated to Gridplus.

@gomesalexandre gomesalexandre merged commit d502db7 into develop Nov 28, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_gridplus_skip_derivation branch November 28, 2025 13:53
@coderabbitai coderabbitai bot mentioned this pull request Jan 11, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gridplus spike: batch pubkeys fetching

1 participant