Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Jan 13, 2026

Description

⚠️ This does not fix one long-standing issue that's still here: if you solved the pin matrix and unlocked your KK, refreshing the app will be a bork, though edge-case enough and more risks than rewards trying to also fix this - will give it a try in a follow-up, but this fixes the guts of connectivity issues.

Root Cause

Infinite loop when switching wallets: The useKeepKeyEventHandler hook's dependency array contained state.walletInfo (an object), causing the effect to re-run on every state update. Combined with the handleConnect callback dispatching SET_WALLET, this created an infinite dispatch loop.

PIN modal not showing: The event handler only attached listeners when localWalletType === KeyManager.KeepKey, but localWalletType is set AFTER wallet initialization. This meant the PINMATRIXREQUEST event was firing before listeners were attached.

Modal closing before PIN entry: After wallet.initialize(), the code immediately dispatched SET_WALLET_MODAL: false without checking if PIN was requested.

Fix

  1. Changed state.walletInfo to state.walletInfo?.deviceId (primitive) + added state.isConnected guard in handleConnect
  2. Attach listeners when state.modalType === KeyManager.KeepKey OR localWalletType === KeyManager.KeepKey (early attachment)
  3. Check features.pinProtection && !features.pinCached after initialize() - if PIN needed, return early instead of closing modal
  4. Added getDevices() check before pairDevice() to handle already-paired WebUSB devices

Issue (if applicable)

closes #11591

Risk

Low - can't break what's broken

Testing

Engineering

  • Connect to Rabby (or any non-KeepKey wallet)
  • Switch to KK (PIN matrix required on device)
  • Ensure shortly after seeing pin matrix on device, it appears in app, without a crash
  • Try this flow back and forth a few times, disconnecting your device to get pin matrix and ensure happy
  • Ensure app refresh with pin matrix required is also happy
  • Ensure full cache cleared with pin matrix required is happy

Operations

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

Screenshots (if applicable)

https://jam.dev/c/c99c9e1c-63f7-429a-a9d3-b1e4d3e13a76
https://jam.dev/c/ac8acfc4-68eb-44cf-ba3b-89d4e1d31731

Summary by CodeRabbit

  • New Features

    • Enhanced device detection to automatically reuse existing wallets when reconnecting.
  • Bug Fixes

    • Improved connection state management to prevent duplicate pairing attempts.
    • Enhanced error logging and diagnostics during wallet initialization.
    • Refined firmware validation with better handling for unavailable versions.

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

@gomesalexandre gomesalexandre requested a review from a team as a code owner January 13, 2026 18:49
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 13, 2026

📝 Walkthrough

Walkthrough

The changes implement a device discovery and reuse mechanism for KeepKey wallet connections. They introduce logic to detect existing WebUSB devices before pairing, refactor firmware validation with fallback handling, add PIN requirement checks, and alias device IDs through the keyring. Event handling is improved to prevent re-entrancy during active connections, and error logging is added to trace connection failures.

Changes

Cohort / File(s) Summary
Device Discovery & Pairing Logic
src/context/WalletProvider/KeepKey/components/Connect.tsx, src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
Added pre-pairing device discovery flow to check existing WebUSB devices via adapter and reuse matching wallets by serial number before attempting new pairing. Reworked firmware validation to proceed with warning if unavailable, or abort if device firmware is outdated. Introduced PIN requirement guard post-wallet initialization and switched device ID to use keyring-aliased ID in local wallet state.
Event Handling & Connection State
src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
Conditional listener attachment based on KeepKey modal state or wallet type instead of unconditional early return. Added re-entrancy guard in handleConnect and handleEvent when connection is active. Tightened effect dependencies to track individual walletInfo fields and connection state.
Error Logging
src/context/WalletProvider/WalletProvider.tsx
Added console.error logging in adapter loading and KeepKey wallet flow error handlers before disconnect operations for better error traceability.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Adapter
    participant Keyring
    participant Device as KeepKey Device
    
    Client->>Adapter: getDevices() - discover existing WebUSB devices
    Adapter-->>Client: Return list of devices
    
    Client->>Keyring: Check if device serial matches known wallet
    alt Device found in Keyring
        Keyring-->>Client: Return cached wallet
        Client->>Client: Reuse existing wallet
    else Device not in Keyring
        Client->>Adapter: Initiate pairing with new device
        Adapter->>Device: Request device connection
        Device-->>Adapter: Device connected
        Adapter-->>Client: Return new wallet
        Client->>Client: Validate firmware
        alt Firmware validation passed
            Client->>Keyring: Alias and store deviceId
            Client->>Client: Complete initialization
        else Firmware outdated or PIN required
            Client->>Client: Abort connection
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Suggested reviewers

  • 0xApotheosis

Poem

🐰 A device found in the cache, no need to pair anew,
KeepKey hops through discovery flows with firmware checks true,
PIN guards and aliases dance, handlers prevent replay—
Connectivity fixed, dear friends, the KeepKey way! 🔑✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: improve kk connectivity' directly addresses the main objective—fixing KeepKey connectivity issues—and accurately reflects the core changes in the PR.
Linked Issues check ✅ Passed The PR implements all key coding requirements from #11591: fixes infinite dispatch loops via dependency optimization, ensures PIN listeners attach early, checks for PIN requirements post-initialization, and calls getDevices() before pairDevice() to reuse existing devices.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to the linked issue objectives: Connect.tsx refactors device discovery and firmware validation, useKeepKeyEventHandler fixes listener attachment timing and re-entrancy, KeepKeyRoutes adds pre-pairing device checks, and WalletProvider adds error logging for debugging connectivity issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ad989b7 and 8305fbf.

📒 Files selected for processing (4)
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/WalletProvider.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
🧠 Learnings (19)
📓 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: gomesalexandre
Repo: shapeshift/web PR: 10879
File: src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx:64-81
Timestamp: 2025-10-22T22:11:22.918Z
Learning: In early WalletConnect POC/features behind a flag, gomesalexandre prioritizes connection correctness/stability over UX polish; minimal safety guards (like preventing concurrent connects) are preferred, while visuals will be wired later by reallybeard.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/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: 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: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 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: 11536
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx:252-265
Timestamp: 2025-12-27T16:02:59.817Z
Learning: When fixing critical bugs in shapeshift/web, gomesalexandre prefers to keep changes minimal and focused on correctness rather than combining bug fixes with code quality improvements like extracting duplicated logic, even when duplication is present.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 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: 10566
File: src/hooks/useLedgerConnectionState.ts:71-95
Timestamp: 2025-09-22T14:28:23.109Z
Learning: gomesalexandre designed useLedgerConnectionState to distinguish between USB device connection state and wallet pairing state. When pairing fails but USB is connected, connectionState should remain 'idle' to allow retries, while 'failed' is reserved for when the USB device is physically disconnected.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

Applied to files:

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

Applied to files:

  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
📚 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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
📚 Learning: 2025-09-22T14:28:23.109Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10566
File: src/hooks/useLedgerConnectionState.ts:71-95
Timestamp: 2025-09-22T14:28:23.109Z
Learning: gomesalexandre designed useLedgerConnectionState to distinguish between USB device connection state and wallet pairing state. When pairing fails but USB is connected, connectionState should remain 'idle' to allow retries, while 'failed' is reserved for when the USB device is physically disconnected.

Applied to files:

  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Connect.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: Wallets are managed via `WalletProvider` context

Applied to files:

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

Applied to files:

  • src/context/WalletProvider/WalletProvider.tsx
📚 Learning: 2025-09-12T13:16:27.004Z
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.

Applied to files:

  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/WalletProvider.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/context/WalletProvider/WalletProvider.tsx
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.

Applied to files:

  • src/context/WalletProvider/WalletProvider.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: Account discovery runs per wallet on connection

Applied to files:

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

Applied to files:

  • src/context/WalletProvider/WalletProvider.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
📚 Learning: 2025-10-22T22:11:22.918Z
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.

Applied to files:

  • src/context/WalletProvider/KeepKey/components/Connect.tsx
📚 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/context/WalletProvider/KeepKey/components/Connect.tsx
📚 Learning: 2025-09-10T15:35:46.223Z
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.

Applied to files:

  • src/context/WalletProvider/KeepKey/components/Connect.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call / Static
🔇 Additional comments (7)
src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts (3)

39-42: LGTM! Listener attachment logic correctly addresses early attachment requirement.

The change allows KeepKey event listeners to be attached when either the KeepKey modal is open OR the local wallet type is KeepKey. This fixes the PIN modal not showing issue by ensuring listeners are attached before PINMATRIXREQUEST fires.


219-221: LGTM! Re-entrancy guard prevents infinite dispatch loop.

The state.isConnected check correctly prevents handleConnect from dispatching SET_WALLET when the wallet is already connected, breaking the infinite loop caused by the effect re-running.


284-287: LGTM! Dependency array correctly uses primitives instead of object reference.

Switching from state.walletInfo (object) to individual primitive fields (deviceId, icon, name) prevents the effect from re-running on every render due to object reference changes. Combined with state.isConnected, this properly breaks the infinite dispatch loop.

src/context/WalletProvider/WalletProvider.tsx (1)

645-648: LGTM! Error logging added for KeepKey connection failures.

Adding console.error(e) before disconnect() improves observability when KeepKey wallet loading fails. This aligns with the codebase pattern and gomesalexandre's preference for console.error debugging. Based on learnings.

src/context/WalletProvider/KeepKey/components/Connect.tsx (3)

137-140: LGTM! PIN requirement check prevents premature modal closure.

The check for pinProtection && !pinCached after initialize() correctly returns early when PIN entry is required. This keeps the modal open for the PINMATRIXREQUEST event to trigger the PIN entry UI, addressing the "modal closed prematurely" issue from the PR objectives.


157-160: LGTM! Using aliased deviceId ensures consistent wallet identification.

Storing aliasDeviceId (from keyring.getAlias()) in local wallet state ensures the deviceId used for reconnection matches the keyring's internal alias mapping. This aligns with the alias mechanism documented in useKeepKeyEventHandler.


76-89: Duplicate pairDevice() call when device exists but wallet not in keyring.

When existingDevices?.length > 0 but existingWallet is not found in the keyring, pairDevice() is called twice:

  1. Line 85 inside the if (existingDevices?.length > 0) block
  2. Line 89 outside the block (always executes when taking the else branch at line 74)

The early pairDevice() call on line 85-86 should instead fall through to line 89, or the outer pairDevice() should be in an else clause.

🐛 Proposed fix
          if (existingDevices?.length > 0) {
            const existingDevice = existingDevices[0]
            const existingWallet = state.keyring.get(existingDevice.serialNumber)
            if (existingWallet) return existingWallet
-            // @ts-ignore
-            return await secondAdapter?.pairDevice()
          }

          // @ts-ignore TODO(gomes): FIXME, most likely borked because of WebUSBKeepKeyAdapter
          return await secondAdapter?.pairDevice()
⛔ Skipped due to learnings
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10566
File: src/hooks/useLedgerConnectionState.ts:71-95
Timestamp: 2025-09-22T14:28:23.109Z
Learning: gomesalexandre designed useLedgerConnectionState to distinguish between USB device connection state and wallet pairing state. When pairing fails but USB is connected, connectionState should remain 'idle' to allow retries, while 'failed' is reserved for when the USB device is physically disconnected.
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: 10879
File: src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx:64-81
Timestamp: 2025-10-22T22:11:22.918Z
Learning: In early WalletConnect POC/features behind a flag, gomesalexandre prioritizes connection correctness/stability over UX polish; minimal safety guards (like preventing concurrent connects) are preferred, while visuals will be wired later by reallybeard.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 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: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SessionProposal.tsx:55-67
Timestamp: 2025-09-13T15:31:38.011Z
Learning: gomesalexandre tested WalletConnect method permissions with MetaMask and WalletConnect's official demo, finding that neither strictly honors method filtering by intersection of requested/supported methods. He prefers aligning with industry standard practices (granting broader EIP-155 method permissions) over theoretical security restrictions when real-world testing shows permissive behavior is the norm.

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.

const existingDevice = existingDevices[0]
const existingWallet = state.keyring.get(existingDevice.serialNumber)
if (existingWallet) return existingWallet
// @ts-ignore
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately for this one we need to use HDD best practices as opposed to typed bits.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/context/WalletProvider/KeepKey/components/Connect.tsx:
- Around line 76-89: The code calls secondAdapter?.pairDevice() twice creating
unreachable/duplicate logic; in the Connect component remove the inner "return
await secondAdapter?.pairDevice()" inside the existingDevices?.length > 0 branch
so that when an existingDevice has no matching wallet it falls through to the
single final "return await secondAdapter?.pairDevice()" path; keep the checks
for existingDevice and state.keyring.get(...) and ensure only one call to
secondAdapter?.pairDevice() remains.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 04681c1 and ad989b7.

📒 Files selected for processing (5)
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/WalletProvider.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.tsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10879
File: src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx:64-81
Timestamp: 2025-10-22T22:11:22.918Z
Learning: In early WalletConnect POC/features behind a flag, gomesalexandre prioritizes connection correctness/stability over UX polish; minimal safety guards (like preventing concurrent connects) are preferred, while visuals will be wired later by reallybeard.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/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: 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: 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: gomesalexandre
Repo: shapeshift/web PR: 10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 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: 10566
File: src/hooks/useLedgerConnectionState.ts:71-95
Timestamp: 2025-09-22T14:28:23.109Z
Learning: gomesalexandre designed useLedgerConnectionState to distinguish between USB device connection state and wallet pairing state. When pairing fails but USB is connected, connectionState should remain 'idle' to allow retries, while 'failed' is reserved for when the USB device is physically disconnected.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.tsx
📚 Learning: 2025-09-22T14:28:23.109Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10566
File: src/hooks/useLedgerConnectionState.ts:71-95
Timestamp: 2025-09-22T14:28:23.109Z
Learning: gomesalexandre designed useLedgerConnectionState to distinguish between USB device connection state and wallet pairing state. When pairing fails but USB is connected, connectionState should remain 'idle' to allow retries, while 'failed' is reserved for when the USB device is physically disconnected.

Applied to files:

  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.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/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx
  • src/context/WalletProvider/KeepKey/components/Connect.tsx
  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
📚 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/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts
📚 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 : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Applied to files:

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

Applied to files:

  • src/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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/context/WalletProvider/KeepKey/components/Pin.tsx
  • src/context/WalletProvider/WalletProvider.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: Wallets are managed via `WalletProvider` context

Applied to files:

  • src/context/WalletProvider/WalletProvider.tsx
📚 Learning: 2025-09-12T13:16:27.004Z
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.

Applied to files:

  • src/context/WalletProvider/WalletProvider.tsx
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.

Applied to files:

  • src/context/WalletProvider/WalletProvider.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: Account discovery runs per wallet on connection

Applied to files:

  • src/context/WalletProvider/WalletProvider.tsx
⏰ 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 (10)
src/context/WalletProvider/KeepKey/components/Pin.tsx (1)

86-86: LGTM!

The [KK:Pin] prefix improves error traceability in logs, aligning with the broader logging enhancements in this PR.

src/context/WalletProvider/WalletProvider.tsx (1)

645-648: LGTM!

Adding console.error(e) before disconnect() ensures errors are captured for debugging before the wallet state is reset. This improves traceability without changing the error handling behavior.

src/context/WalletProvider/NewWalletViews/routes/KeepKeyRoutes.tsx (2)

95-95: LGTM!

Correctly added state.keyring to the dependency array since it's used within the callback for state.keyring.get(existingDevice.serialNumber).


70-78: Address WebUSBKeepKeyAdapter type and implementation issues.

The device reuse logic is safe with optional chaining, but the code contains developer-added TODO comments (lines 80 and beyond) indicating known issues with WebUSBKeepKeyAdapter. A TODO in config.ts (line 369) notes the adapter is not properly exported as a type from the hdwallet package, causing the @ts-ignore suppressions on pairDevice() calls. This pattern is repeated across multiple files (Connect.tsx, WalletProvider.tsx), suggesting a systemic issue that needs resolution rather than workaround comments. The getDevices() call is protected by optional chaining and should be safe, but the pairDevice() call on line 81 lacks the same protection and may encounter runtime issues.

src/context/WalletProvider/KeepKey/hooks/useKeepKeyEventHandler.ts (3)

38-42: Good fix for early listener attachment.

Attaching listeners when state.modalType === KeyManager.KeepKey (in addition to localWalletType) ensures PINMATRIXREQUEST events are caught even before localWalletType is set during wallet initialization. This correctly addresses the PIN modal not showing issue.


219-221: Critical fix for the infinite loop issue.

The state.isConnected guard prevents handleConnect from dispatching SET_WALLET when already connected. Without this, the SET_WALLET dispatch would update state.walletInfo, triggering a re-render and re-attaching listeners, causing handleConnect to fire again in an infinite loop.


283-286: Correct dependency refinement to primitives.

Using state.walletInfo?.deviceId, state.walletInfo?.icon, and state.walletInfo?.name instead of state.walletInfo (object) prevents unnecessary effect re-runs due to object reference changes. Adding state.isConnected is required for the new guard in handleConnect.

src/context/WalletProvider/KeepKey/components/Connect.tsx (3)

113-116: Good consolidation of firmware validation.

The check now properly guards against proceeding when firmware is outdated: only validate if latestFirmware is available, and set error if the device firmware doesn't meet the requirement.


131-134: Critical fix for premature modal closure.

This guard ensures the flow returns early if the device requires PIN entry (pinProtection && !pinCached). The PINMATRIXREQUEST event handler will open the PIN modal. Without this return, the code would proceed to dispatch SET_WALLET_MODAL: false, closing the modal before PIN entry could occur.


151-154: Correct use of aliasDeviceId for local wallet storage.

Using the aliased device ID ensures consistency with how KeepKey device IDs are resolved elsewhere (e.g., in handleConnect). This prevents mismatches when comparing device IDs later.

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.

KeepKey Connectivity borked

2 participants