Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Nov 13, 2025

Description

Initial Trezor wire-up.

Note, while Trezor Suite prompts have been reduced to the max for this base PR, account management is still absolute hell in terms of Trezor Suite pubkeys prompts and needs polish.
This will require quite the refactor both in web and hdwallet in terms of handling batching/caching of pubkeys derivation, ticketed in #11082.

- [x] Pair 
- [x] Add Trezor Wallet flag
- [x] Turn WC dApps on for Trezor
- [x] Ensure account management add accounts modal pops up on Trezor pair
- [x] Perhaps need the same `isTrezor()` checks as Ledger re: skipping on-device derivation in many places in the app in `getAddress()`, to avoid Trezor Suite popups madness
- [x] Triple check unique setup device ID is used 
- [x] Ensure Solana is present in Account Management modal 
- [x] E2E test EVM chains
  - [x] Message signing
  - [x] Structured message signing
  - [x] Tx signing
- [ ] E2E chain UTXOs
  - [x] Ensure all scriptTypes derived
  - [x] Test Txs for all script types 
  - [x] Sanity test BCH is happy
- [x] E2E test Solana
  - [x] Test sign Solana Txs
- [x] Swapper
  - [x] Test a few pairs and ensure the whole thing performs well 
- [ ] ~~Refactor Account Management to batch pubkeys request and/or prefetch many in a row (derivation only, not actual account fetching). Perhaps custom Trezor code?~~ Follow-up in https://github.com/shapeshift/web/issues/11082, this is going to be a huge boi 

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

Test signing is happy for:

  • EVM Txs
  • EVM sends
  • EVM structured data message signing (e.g CoW)
  • EVM unstructured message signing (try with https://react-app.walletconnect.com/)
  • UTXO Txs/Sends
  • Solana Txs
  • Solana sends

Also test that:

  • You're able to derive accounts for all Trezor supported chains
  • Add accounts modal pops up on initial (fresh) Trezor pairing
  • Reconnecting a Trezor rehydrates its accounts
  • WC dApps is happy for Trezor

Engineering

  • &

Operations

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

None yet!

Screenshots (if applicable)

Solana

  • Sign Tx

https://jam.dev/c/30deaf1f-b4e2-4e20-90ef-2d44a8cb36cb

EVM

  • Structured Signing

https://jam.dev/c/3c4151fe-5c5f-41d4-85a5-7440f952809e

  • Message Signing

https://jam.dev/c/2e285d30-9b10-4837-a1b8-a3836d3e0411

  • Tx signing

https://jam.dev/c/f00017de-5d8c-4791-8580-1338fe48f4c3

BTC

  • All script types derived

https://jam.dev/c/4c507308-1b44-4d53-af53-e8d853bb3a17

  • All script types Txs happy

https://jam.dev/c/6c5243a3-4385-4acf-934e-e7c7f3e0c6f3

  • BCH is happy

https://jam.dev/c/bf3bdabf-2230-46b8-8fee-c297fd8559cf

Swapper smoke test

https://jam.dev/c/9208bf88-f19b-4048-b4cd-296902940e98

Summary by CodeRabbit

  • New Features

    • Added Trezor hardware wallet support with device pairing, account discovery, and transaction signing.
    • Added feature flag to enable/disable Trezor wallet integration.
  • Improvements

    • Enhanced address derivation for hardware wallets including Trezor.
    • Updated hardware wallet dependencies to latest patch version.
  • Localization

    • Added Trezor-related UI text and messages in English translations.

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

gomesalexandre and others added 4 commits November 13, 2025 01:09
Integrate Trezor hardware wallet following Ledger pattern with manual chain
addition workflow.

Core integration:
- Add Trezor to KeyManager enum
- Add TrezorConfig with adapter and routes
- Register in SUPPORTED_WALLETS with lazy-loaded components
- Add TrezorMenu for connected wallet dropdown

Components created:
- Connect.tsx - Simple pairing flow with Trezor Connect popup
- Chains.tsx - Manual chain addition interface
- Success.tsx - Connection success state
- Failure.tsx - Error handling
- TrezorMenu.tsx - Connected wallet menu

Icon and branding:
- Create TrezorIcon component using shield logo
- Follows Chakra UI createIcon pattern

Chain support:
- Manual addition like Ledger (not automatic discovery)
- Skip account discovery for isTrezor wallets
- Support all EVM chains, Bitcoin, Dogecoin, Litecoin, BCH, Solana

Dependencies:
- @shapeshiftoss/[email protected]
- @shapeshiftoss/[email protected]

Translations:
- Add walletProvider.trezor section with all UI strings
- Simple "Connect your Trezor device and click Pair" flow
- No existing device complexity (kept simple)

Feature flags ready:
- AccountManagementTrezor for future account management UI

Builds successfully with no TypeScript errors.

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

Co-Authored-By: Claude <[email protected]>
CSP additions:
- Add trezor.ts CSP with frame-src for connect.trezor.io
- Add connect-src for Trezor Suite websocket (ws://127.0.0.1:21335)
- Import and register in headers/csps/index.ts

TypeScript fixes:
- Add TrezorAdapter to AdaptersByKeyManager type
- Add TrezorAdapter to SupportedWalletInfoByKeyManager type
- Add TrezorConnectArgs type for manifest configuration
- Add getKeyManagerOptions case for Trezor with proper manifest

NewWalletViews integration:
- Create TrezorRoutes with simple PairBody flow
- Add Trezor to HardwareWalletsSection (between Ledger and KeepKey)
- Register route in NewWalletViewsSwitch

Component improvements:
- Use official Trezor symbol SVG from trezor-symbol-white-rgb.svg
- Simplify Connect component (remove feature flags)
- Wrap PairBody element in useMemo for performance
- Update manifest email to [email protected]

Discovery fixes:
- Add isTrezor check in useDiscoverAccounts
- Skip auto-discovery for Trezor (manual chain addition like Ledger)

All changes enable Trezor to appear in wallet selector and work without
CSP violations or TypeScript errors.

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

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

coderabbitai bot commented Nov 13, 2025

📝 Walkthrough

Walkthrough

Adds Trezor hardware wallet support: feature flag, UI (icon, routes, pairing), wallet provider wiring and config, CSP entry, translations, pubKey propagation across adapters/hooks, type updates, dependency bumps, and test/dev env adjustments. Changes mirror existing Ledger integration patterns.

Changes

Cohort / File(s) Summary
Feature flag & config
\.env`, `.env.development`, src/config.ts, src/state/slices/preferencesSlice/preferencesSlice.ts, src/test/mocks/store.ts`
Add VITE_FEATURE_TREZOR_WALLET (false prod, true dev); validator in config and TrezorWallet feature flag added and initialized in prefs and mocks.
Wallet provider wiring
src/context/WalletProvider/*
Add KeyManager.Trezor; types updated to include TrezorAdapter; add TrezorConfig, lazy TrezorMenu, SUPPORTED_WALLETS entry, getKeyManagerOptions handling for Trezor manifest args.
Trezor routes & UI
src/context/WalletProvider/NewWalletViews/routes/TrezorRoutes.tsx, src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx, src/context/WalletProvider/NewWalletViews/sections/HardwareWalletsSection.tsx, src/context/WalletProvider/SelectModal.tsx
New TrezorRoutes pairing flow, route registration, hardware wallet option and feature-flag gating, and select modal conditional rendering.
Trezor components & config
src/context/WalletProvider/Trezor/config.ts, src/context/WalletProvider/Trezor/components/TrezorMenu.tsx, src/components/Icons/TrezorIcon.tsx
New TrezorConfig, TrezorMenu component, and TrezorIcon SVG component.
Security headers
headers/csps/trezor.ts, headers/csps/index.ts
Add CSP for Trezor Connect and Bridge ports; export in CSPs list.
Translations
src/assets/translations/en/main.json
Add ledger.trezor translation block (verify, errors, connect).
Type & adapter changes
packages/chain-adapters/src/evm/types.ts, packages/chain-adapters/src/evm/EvmBaseAdapter.ts, packages/chain-adapters/src/solana/SolanaChainAdapter.ts, packages/chain-adapters/src/types.ts
Add optional pubKey?: string to send/build inputs and propagate pubKey through address resolution paths.
PubKey propagation & hooks
src/components/Modals/Send/utils.ts, src/components/Modals/FiatRamps/views/FiatForm.tsx, src/components/Modals/Receive/ReceiveInfo.tsx, src/components/MultiHopTrade/**, src/pages/Lending/**, src/lib/utils/thorchain/index.ts, src/hooks/**, src/lib/utils/index.ts, src/plugins/**, src/lib/utils/thorchain/index.ts
Treat Trezor like Ledger/GridPlus for skipDeviceDerivation and pubKey derivation across send/receive, trade, fee, lending, Thorchain, WalletConnect, and transaction subscriber flows; add isTrezorHDWallet guard.
App integration & discovery
src/context/AppProvider/hooks/useDiscoverAccounts.tsx, src/context/WalletProvider/NewWalletViews/*, src/context/WalletProvider/types.ts
Discovery guard and account flows extended to handle Trezor; KeyManager types updated.
Dev & deps
package.json, src/setupVitest.ts
Bump @shapeshiftoss/hdwallet-* deps from 1.62.6 → 1.62.9; expand vitest alias regex to include hdwallet-trezor import resolution.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant SelectModal as Select Modal
    participant TrezorRoutes as TrezorRoutes
    participant Adapter as Trezor Adapter
    participant Device as Trezor Device
    participant Store as App Store

    User->>SelectModal: Click "Connect Trezor"
    SelectModal->>SelectModal: Check feature flag
    alt Enabled
        SelectModal->>TrezorRoutes: Navigate to /trezor/connect
        User->>TrezorRoutes: Click "Pair Device"
        TrezorRoutes->>Adapter: getAdapter(KeyManager.Trezor)
        TrezorRoutes->>Device: adapter.pairDevice()
        Device-->>TrezorRoutes: deviceId / error
        alt Success
            TrezorRoutes->>Store: SET_WALLET, SET_IS_CONNECTED, store deviceId
            TrezorRoutes->>TrezorRoutes: Hide modal, loading=false
        else Error
            TrezorRoutes->>TrezorRoutes: Set error, loading=false
        end
    else Disabled
        SelectModal->>User: Trezor option hidden
    end
Loading
sequenceDiagram
    participant Hook as Trade/Send Hook
    participant Wallet as Wallet Context
    participant Adapter as Chain Adapter
    participant Quote as Quote Service

    Hook->>Wallet: Inspect wallet type & accountId
    alt Wallet is Ledger or Trezor + accountId
        Hook->>Hook: pubKey = fromAccountId(accountId).account
    else
        Hook->>Hook: pubKey = undefined
    end
    Hook->>Adapter: Call adapter.getAddress/buildTx with pubKey?
    Adapter->>Adapter: Resolve address (use pubKey if provided)
    Adapter-->>Hook: Resolved address
    Hook->>Quote: Request quote with resolved address
    Quote-->>Hook: Quote result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • src/context/WalletProvider/config.ts: Trezor manifest args, lazy adapter wiring and SUPPORTED_WALLETS integration.
  • PubKey propagation consistency across chain adapters, trade hooks, WalletConnect, and signing flows.
  • Device pairing flow (TrezorRoutes): error handling, dispatch ordering, and persistence of deviceId.
  • Type coverage: ensure all switch/case and type unions correctly handle KeyManager.Trezor.

Possibly related PRs

Suggested labels

high risk

Suggested reviewers

  • NeOMakinG
  • kaladinlight

Poem

🐰 I dug a tunnel, found a Trezor bright,
Paired and hummed beneath the moonlight.
PubKeys hopping, icons in a row,
Feature-flagged burrow where cold-wallets go.
Celebrate with carrot code—secure and right! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: wire up hdwallet-trezor' directly and clearly describes the primary change: integrating/wiring up Trezor support via the hdwallet-trezor library.
Linked Issues check ✅ Passed All three acceptance criteria from #10892 are met: users can connect Trezor (TrezorRoutes, pairDevice), view accounts (useDiscoverAccounts, pubKey handling), and sign transactions/messages (buildSendTransaction, buildCustomTx implementations).
Out of Scope Changes check ✅ Passed All changes are in scope: environment variables and feature flags for Trezor, CSP headers, hdwallet dependency upgrades, adapter integration, UI components (icons, routes, menus), and transaction signing support across EVM and Solana chains.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat_trezor

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: add Trezor wallet support to shapeshiftWeb feat: wire up hdwallet-trezor Nov 13, 2025
gomesalexandre and others added 18 commits November 13, 2025 10:20
Add TrezorWallet feature flag:
- Add to FeatureFlags type in preferencesSlice
- Add VITE_FEATURE_TREZOR_WALLET to config.ts (default: false)
- Set false in .env (production)
- Set true in .env.development (development)
- Add feature flag check in SelectModal (hide Trezor if disabled)

Clean up Trezor constants:
- Rename availableTrezorAppAssetIds → supportedTrezorAssetIds
- Rename availableTrezorAppChainIds → supportedTrezorChainIds
- Remove 'App' terminology (Trezor doesn't have apps like Ledger)
- Update usages in Chains.tsx

Trezor handles all supported chains natively without switching apps.

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

Co-Authored-By: Claude <[email protected]>
Chain selection fix:
- Import supportedTrezorChainIds in SelectChain component
- Add Trezor case in availableChainIds logic (was falling back to walletSupportedChainIds which lacked Solana)
- Now Trezor shows all supported chains: BTC, DOGE, BCH, LTC, ETH, SOL + all EVM
- Add debug logs to investigate chain filtering

PubKey device derivation bypass:
- Add isTrezor import to all files that check isLedger for pubKey
- Update all pubKey conditionals from isLedger(wallet) to (isLedger(wallet) || isTrezor(wallet))
- This prevents device popups during transaction subscriptions and address derivation

Files updated:
- SelectChain.tsx - Chain selection modal
- useTransactionsSubscriber.ts - Transaction subscriptions
- thorchain/index.ts - THORChain address derivation (2 locations)
- FiatForm.tsx - Fiat ramp address derivation
- useTradeNetworkFeeCryptoBaseUnit.tsx - Trade fee calculations (3 locations)
- useLendingQuoteQuery.ts - Lending receive address

Without this fix, subscribing to transactions or deriving addresses would
trigger Trezor popups unnecessarily. With pubKey provided, chain adapters
can derive addresses locally without device interaction.

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

Co-Authored-By: Claude <[email protected]>
Replace raw.githubusercontent.com URLs with cdn.jsdelivr.net/gh to fix
OpenAPI generator fetch failures.

URL pattern change:
- Before: https://raw.githubusercontent.com/shapeshift/unchained/{branch}/path
- After:  https://cdn.jsdelivr.net/gh/shapeshift/unchained@{branch}/path

JSDelivr CDN is more reliable and handles rate limiting better than
raw.githubusercontent.com.

Updated all chains: avalanche, bitcoin, bitcoincash, bnbsmartchain, dogecoin,
ethereum, litecoin, optimism, polygon, gnosis, arbitrum, arbitrum-nova, base,
solana, thorchain, thorchain-v1, mayachain.

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

Co-Authored-By: Claude <[email protected]>
…ration

Download swagger files locally to avoid network timeout issues with JSDelivr.

Changes:
- Create packages/unchained-client/swagger/ directory
- Download 12 swagger.json files using curl from JSDelivr CDN
- Update openapitools.json to use local files (#{cwd}/swagger/*.swagger.json)

Chains using local files:
ethereum, bitcoin, bnbsmartchain, gnosis, optimism, litecoin, dogecoin,
bitcoincash, avalanche, arbitrum, arbitrumNova, base

Chains still using remote (working):
cosmos, mayachain, solana, thorchain, thorchainV1, polygon

This fixes OpenAPI generator timeouts and makes builds reproducible.

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

Co-Authored-By: Claude <[email protected]>
…ibraries

Complete the migration to local swagger files for all unchained chains.

Added remaining swagger files (6 more):
- cosmos.swagger.json (33K)
- mayachain.swagger.json (28K)
- polygon.swagger.json (25K)
- solana.swagger.json (43K)
- thorchain.swagger.json (30K)
- thorchainV1.swagger.json (23K)

Updated openapitools.json:
- All 18 chains now use local files: #{cwd}/swagger/*.swagger.json
- Zero remote URLs remaining (was failing with timeouts)

Build verification:
- yarn build:packages completes successfully
- All chains generate with exit code 0
- Total swagger files: 18 chains (~500KB)

This makes builds reproducible, faster, and immune to network issues.

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

Co-Authored-By: Claude <[email protected]>
Update all @shapeshiftoss/hdwallet-* packages to 1.62.5-alpha.trezor.10 to fix
version resolution issues.

Problem:
- Web had 1.62.4-alpha.239 with exact version
- hdwallet-trezor-connect dependency had ^1.62.4-alpha.239 (caret)
- Yarn resolved to published 1.62.5 which has old code
- Wallet showed old flags (_supportsBSC: false, etc.)

Solution:
- Published new 1.62.5-alpha.trezor.10 to Verdaccio
- Update ALL hdwallet packages to this version (no carets)
- This version has all correct flags including Solana support

Test mock fix:
- Add TrezorWallet: false to featureFlags mock

All hdwallet packages now in sync at 1.62.5-alpha.trezor.10.

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

Co-Authored-By: Claude <[email protected]>
Update all @shapeshiftoss/hdwallet-* packages to 1.62.6-trezor.1 to fix
version resolution and ensure correct Trezor support flags.

Verified with yarn why:
- Both @shapeshiftoss/hdwallet-trezor-connect and direct dependencies
  now resolve to 1.62.6-trezor.1
- No more conflicts with published 1.62.5

This version has all correct flags:
- _supportsBSC: true
- _supportsPolygon: true
- _supportsGnosis: true
- _supportsOptimism: true
- _supportsSolana: true

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

Co-Authored-By: Claude <[email protected]>
Add pubKey parameter for Trezor in Receive and Send flows to prevent
unnecessary device popups.

Receive modal (ReceiveInfo.tsx):
- Add pubKey to initial address loading (line 111-115)
- Add pubKey to address verification (line 149-153)
- Check for both Ledger and Trezor wallet types
- Prevents popup when opening Receive modal

Send modal (utils.ts):
- Import isTrezor from @shapeshiftoss/hdwallet-trezor
- Add pubKey to Solana buildSendTransaction input (line 272-275)
- Add pubKey to sender address derivation (line 300) - Trezor only
- Prevents popup during transaction building

With pubKey provided, chain adapters derive addresses locally without device
interaction, only showing popup for transaction signing confirmation.

Matches GridPlus pattern from PR #10767.

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

Co-Authored-By: Claude <[email protected]>
Update buildSendTransaction to spread pubKey into txToSign object if provided.

Changes:
- Spread input.pubKey into txToSign object: {...txToSign, ...(input.pubKey ? { pubKey: input.pubKey } : {})}
- Return type stays the same (pubKey is optional field in txToSign)

This allows pubKey to flow through to signTransaction for Trezor/Ledger wallets,
preventing unnecessary device popups during Solana transaction signing.

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

Co-Authored-By: Claude <[email protected]>
Update to include Solana pubKey bypass fix from hdwallet.

This version adds early return in solanaGetAddress if pubKey is provided,
preventing device popup when deriving Solana addresses with known pubKeys.

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

Co-Authored-By: Claude <[email protected]>
Add pubKey?: string to BuildSendTxInput type to support device derivation bypass.

Changes:
- Add pubKey?: string to BuildSendTxInput<T extends ChainId> type
- Fixes TypeScript errors in SolanaChainAdapter.ts
- Allows pubKey to be passed through buildSendTransaction

This enables Trezor/Ledger to provide pubKey for address derivation without
device interaction, completing the Solana pubKey bypass implementation.

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

Co-Authored-By: Claude <[email protected])
Add Trezor to WalletConnect dApps supported wallets list.

Changes:
- Add TrezorHDWallet type import to lib/utils/index.ts
- Create isTrezorHDWallet utility function (checks vendor === 'Trezor')
- Add Trezor case to useIsWalletConnectToDappsSupportedWallet hook
- Returns true for Trezor (supports EIP-712 via ethSignTypedData)

Trezor users can now connect to dApps via WalletConnect, similar to KeepKey
and Native wallets. Trezor supports all required signing methods including
EIP-712 typed data signing.

Matches GridPlus pattern from PR #10767.

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

Co-Authored-By: Claude <[email protected]>
Add pubKey parameter to getAddress call in WalletConnect EIP155 request handler
to prevent device popup when deriving sender address.

Changes:
- Import isTrezor and TrezorHDWallet type
- Update assertSupportsEthSignTypedData to include TrezorHDWallet
- Add pubKey to getAddress call with isTrezor check (line 94-98)
- Prevents popup when WalletConnect dApp requests transaction

This completes Trezor integration with WalletConnect dApps - all signing
methods now work without unnecessary popups.

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

Co-Authored-By: Claude <[email protected]>
Add pubKey parameter to BuildCustomTxInput type and pass it through the
buildCustomTx flow for Trezor wallet.

Changes:
- Add pubKey?: string to BuildCustomTxInput type (evm/types.ts)
- Extract pubKey from input and pass to getAddress in buildCustomTx
- Pass pubKey to buildCustomTx call in EIP155RequestHandlerUtil if isTrezor

This prevents device popup when WalletConnect dApps request custom transactions
from Trezor. The pubKey allows address derivation without device interaction,
only showing popup for actual transaction signing.

Completes Trezor WalletConnect dApps integration with no unnecessary popups.

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

Co-Authored-By: Claude <[email protected]>
@gomesalexandre gomesalexandre requested a review from a team as a code owner November 13, 2025 15:35
@gomesalexandre
Copy link
Contributor Author

Opening for early review - to be tested with shapeshift/hdwallet#736 published locally with Verdaccio - or just review conceptually and wait for hdwallet-trezor to make it to npm!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
.env.development (1)

78-78: Consider reordering for consistency.

The linter suggests placing VITE_FEATURE_TREZOR_WALLET before VITE_FEATURE_TX_HISTORY_BYE_BYE to maintain alphabetical ordering.

.env (1)

20-20: Feature flag follows conventions; consider alphabetical ordering.

The Trezor wallet feature flag follows the existing naming convention and is appropriately disabled by default. The static analysis tool suggests reordering for consistency with alphabetical sorting of feature flags.

Consider reordering to maintain alphabetical consistency:

 VITE_FEATURE_LEDGER_WALLET=true
+VITE_FEATURE_TREZOR_WALLET=false
 VITE_FEATURE_WALLET_CONNECT_V2=true
-VITE_FEATURE_TREZOR_WALLET=false
TREZOR_POPUP_BATCHING_ANALYSIS.md (1)

1-50: Consider tidying markdown formatting before merge (optional polish).

The document is well-structured and comprehensive. Static analysis flags several markdown formatting items that could be addressed as optional polish:

  • Add language identifiers to code blocks (e.g., ```typescript) — currently missing at lines 47, 76, 224, 1024
  • Convert emphasis (**bold**) used as section headers to actual markdown headings (###)

However, per team patterns, this formatting polish can be deferred to a follow-up if you prefer to prioritize getting the analysis/planning content reviewed.

Copy link
Collaborator

@NeOMakinG NeOMakinG left a comment

Choose a reason for hiding this comment

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

https://jam.dev/c/96c3208e-2bc3-47b9-af74-9a4b48ba6eca

Tested with the hdwallet PR, seems to be working as expected minus the btc send to segwit, not sure if it's a trezor issue or a us issue thought!

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

📜 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 b8286f5 and 6a2b3a1.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (25)
  • .env (1 hunks)
  • .env.development (1 hunks)
  • headers/csps/index.ts (2 hunks)
  • package.json (1 hunks)
  • src/assets/translations/en/main.json (1 hunks)
  • src/components/Modals/FiatRamps/views/FiatForm.tsx (2 hunks)
  • src/components/Modals/Receive/ReceiveInfo.tsx (1 hunks)
  • src/components/Modals/Send/utils.ts (3 hunks)
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx (2 hunks)
  • src/config.ts (1 hunks)
  • src/context/AppProvider/hooks/useDiscoverAccounts.tsx (2 hunks)
  • src/context/WalletProvider/KeyManager.ts (1 hunks)
  • src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx (2 hunks)
  • src/context/WalletProvider/NewWalletViews/sections/HardwareWalletsSection.tsx (4 hunks)
  • src/context/WalletProvider/config.ts (7 hunks)
  • src/context/WalletProvider/types.ts (2 hunks)
  • src/hooks/useAddAccountsGuard/useAddAccountsGuard.tsx (1 hunks)
  • src/hooks/useTransactionsSubscriber.ts (2 hunks)
  • src/lib/utils/index.ts (2 hunks)
  • src/lib/utils/thorchain/index.ts (3 hunks)
  • src/plugins/walletConnectToDapps/hooks/useIsWalletConnectToDappsSupportedWallet.tsx (2 hunks)
  • src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts (3 hunks)
  • src/setupVitest.ts (1 hunks)
  • src/state/slices/preferencesSlice/preferencesSlice.ts (2 hunks)
  • src/test/mocks/store.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • src/config.ts
  • src/context/AppProvider/hooks/useDiscoverAccounts.tsx
  • src/hooks/useTransactionsSubscriber.ts
  • src/context/WalletProvider/KeyManager.ts
  • src/components/Modals/Receive/ReceiveInfo.tsx
  • src/plugins/walletConnectToDapps/hooks/useIsWalletConnectToDappsSupportedWallet.tsx
  • src/assets/translations/en/main.json
  • headers/csps/index.ts
  • src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx
  • src/test/mocks/store.ts
  • src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts
  • src/lib/utils/thorchain/index.ts
  • package.json
  • src/components/Modals/Send/utils.ts
🧰 Additional context used
🧠 Learnings (33)
📓 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: 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: 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: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:0-0
Timestamp: 2025-09-12T11:56:19.437Z
Learning: gomesalexandre rejected verbose try/catch error handling for address validation in Tenderly integration (PR #10461), calling the approach "ugly" but still implemented safety measures in commit ad7e424b89, preferring cleaner safety implementations over defensive programming patterns.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 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: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:69-74
Timestamp: 2025-09-10T15:35:36.547Z
Learning: gomesalexandre dismissed alt text accessibility suggestion with "meh" in PR #10458 for EIP155SignTypedDataConfirmation.tsx Image component, consistent with team pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
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: 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-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/sections/HardwareWalletsSection.tsx
  • src/context/WalletProvider/types.ts
  • src/context/WalletProvider/config.ts
  • src/lib/utils/index.ts
  • src/hooks/useAddAccountsGuard/useAddAccountsGuard.tsx
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/context/WalletProvider/NewWalletViews/sections/HardwareWalletsSection.tsx
  • src/context/WalletProvider/types.ts
  • src/context/WalletProvider/config.ts
  • src/lib/utils/index.ts
  • src/hooks/useAddAccountsGuard/useAddAccountsGuard.tsx
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/NewWalletViews/sections/HardwareWalletsSection.tsx
  • src/hooks/useAddAccountsGuard/useAddAccountsGuard.tsx
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/NewWalletViews/sections/HardwareWalletsSection.tsx
📚 Learning: 2025-08-22T13:02:38.078Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/Explore/Explore.tsx:91-92
Timestamp: 2025-08-22T13:02:38.078Z
Learning: In the ShapeShift web codebase, feature flags are consistently used as string literals with the useFeatureFlag hook (e.g., useFeatureFlag('RfoxFoxEcosystemPage')), not as enums. The hook accepts keyof FeatureFlags which provides type safety through the TypeScript type system rather than requiring an enum. This is the established pattern used throughout the entire codebase.

Applied to files:

  • src/state/slices/preferencesSlice/preferencesSlice.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/types.ts
  • src/context/WalletProvider/config.ts
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-08-29T18:09:45.982Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10376
File: vite.config.mts:136-137
Timestamp: 2025-08-29T18:09:45.982Z
Learning: In the ShapeShift web repository vite.config.mts, the commonjsOptions.exclude configuration using bare package name strings like ['shapeshiftoss/caip', 'shapeshiftoss/types'] works correctly for excluding specific packages from CommonJS transformation, despite theoretical concerns about module ID matching patterns.

Applied to files:

  • src/setupVitest.ts
📚 Learning: 2025-08-05T22:41:35.473Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.

Applied to files:

  • src/setupVitest.ts
  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-09-04T10:18:34.140Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10427
File: src/hooks/useActionCenterSubscribers/useSwapActionSubscriber.tsx:40-40
Timestamp: 2025-09-04T10:18:34.140Z
Learning: In the shapeshift/web codebase, src/state/slices/selectors.ts uses wildcard exports (`export * from './[sliceName]/selectors'`) to re-export all selectors from individual slice selector files, making them available through the barrel import. This means selectors like selectTxByFilter from txHistorySlice/selectors are properly accessible via '@/state/slices/selectors' even though they don't appear in explicit named exports.

Applied to files:

  • src/setupVitest.ts
📚 Learning: 2025-09-12T09:48:46.305Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-12T09:48:46.305Z
Learning: In WalletConnect signing flows dealing with structured message data (like StructuredField.value in StructuredMessage.tsx), gomesalexandre prefers using `any` type for values representing dynamic Solidity types from external API responses, consistent with their approach to other external API parsing in WalletConnect flows.

Applied to files:

  • src/lib/utils/index.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 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/hooks/useAddAccountsGuard/useAddAccountsGuard.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/hooks/useAddAccountsGuard/useAddAccountsGuard.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/hooks/useReceiveAddress.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/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.

Applied to files:

  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
📚 Learning: 2025-08-08T15:00:22.321Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.

Applied to files:

  • src/components/MultiHopTrade/hooks/useReceiveAddress.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/hooks/useReceiveAddress.tsx
📚 Learning: 2025-08-11T09:45:51.174Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10219
File: src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx:175-180
Timestamp: 2025-08-11T09:45:51.174Z
Learning: gomesalexandre prefers truthy checks over explicit boolean comparisons (e.g., `walletSupportsSellAssetChain` instead of `walletSupportsSellAssetChain === true`) when dealing with tri-state values (boolean | null) in TypeScript, as the falsy behavior for null/undefined is intentional and acceptable.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • src/components/MultiHopTrade/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.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/hooks/useReceiveAddress.tsx
  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-08-14T17:54:32.563Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx:97-108
Timestamp: 2025-08-14T17:54:32.563Z
Learning: In ReusableLpStatus component (src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx), the txAssets dependency is stable from first render because poolAsset, baseAsset, actionSide, and action are all defined first render, making the current txAssetsStatuses initialization pattern safe without needing useEffect synchronization.

Applied to files:

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

Applied to files:

  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-08-27T09:47:06.275Z
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.

Applied to files:

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

Applied to files:

  • src/components/Modals/FiatRamps/views/FiatForm.tsx
📚 Learning: 2025-09-09T06:01:24.130Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10424
File: .env.production:3-3
Timestamp: 2025-09-09T06:01:24.130Z
Learning: In Vite, environment variables have a fallback mechanism where .env.production takes precedence over .env, but variables defined only in .env will still be available in the production environment if not overridden in .env.production.

Applied to files:

  • .env
🧬 Code graph analysis (3)
src/context/WalletProvider/NewWalletViews/sections/HardwareWalletsSection.tsx (2)
src/components/Icons/TrezorIcon.tsx (1)
  • TrezorIcon (3-12)
src/context/WalletProvider/Trezor/config.ts (1)
  • TrezorConfig (8-17)
src/state/slices/preferencesSlice/preferencesSlice.ts (1)
src/config.ts (1)
  • getConfig (221-223)
src/context/WalletProvider/config.ts (3)
src/context/WalletProvider/Trezor/components/TrezorMenu.tsx (1)
  • TrezorMenu (9-11)
src/context/WalletProvider/Trezor/config.ts (1)
  • TrezorConfig (8-17)
src/context/WalletProvider/WalletConnectV2/constants.ts (1)
  • EthereumProviderOptions (150-163)
🪛 dotenv-linter (4.0.0)
.env

[warning] 20-20: [UnorderedKey] The VITE_FEATURE_TREZOR_WALLET key should go before the VITE_FEATURE_WALLET_CONNECT_TO_DAPPS key

(UnorderedKey)

.env.development

[warning] 12-12: [UnorderedKey] The VITE_FEATURE_TREZOR_WALLET key should go before the VITE_FEATURE_VULTISIG_WALLET key

(UnorderedKey)

⏰ 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 (13)
src/components/MultiHopTrade/hooks/useReceiveAddress.tsx (1)

5-5: LGTM! Trezor correctly integrated into skip-device-derivation logic.

The import and logic extension properly treat Trezor wallets consistently with Ledger and GridPlus, avoiding unnecessary device prompts during receive address derivation. The boolean grouping correctly validates wallet existence before invoking any type guard.

Also applies to: 101-102

src/lib/utils/index.ts (1)

9-48: Trezor type guard import and implementation verified

The vendor string 'Trezor' is confirmed correct and used consistently across the codebase (KeyManager.Trezor, routes, config, etc.). The type guard follows the established pattern of KeepKey, Keplr, Native, GridPlus, and WalletConnectV2 guards. The new isTrezorHDWallet is already imported and actively used in useIsWalletConnectToDappsSupportedWallet.tsx, confirming proper integration. The optional suggestion to centralize vendor strings remains a valid follow-up but does not affect the correctness of this change.

src/hooks/useAddAccountsGuard/useAddAccountsGuard.tsx (2)

13-13: LGTM! Clean device-change detection.

The deviceId tracking ensures that when a user switches to a different Trezor device (or any hardware wallet device), hasCheckedRef resets and the add-accounts modal will appear again. This aligns well with the PR objective to ensure the modal appears on Trezor pair.

Also applies to: 20-20, 29-35


40-45: LGTM! Trezor integration follows established pattern.

The guard now includes Trezor alongside Ledger and GridPlus, ensuring the add-accounts modal opens for newly paired Trezor devices when no accounts exist. This is consistent with the existing hardware wallet flow.

.env.development (1)

12-12: LGTM!

The development environment flag enables local testing of Trezor integration, following the established pattern for wallet feature flags.

.env (1)

20-20: LGTM!

The production default (false) ensures safe rollout, while development overrides enable local testing. Placement after the Ledger flag is logical.

src/context/WalletProvider/NewWalletViews/sections/HardwareWalletsSection.tsx (1)

10-10: LGTM!

The Trezor wallet integration follows the established Ledger pattern precisely: imports config/icon, creates a connection handler, checks the feature flag, and conditionally renders the wallet option. The route /trezor/connect parallels Ledger's structure.

Also applies to: 15-15, 72-75, 88-88, 105-113

src/state/slices/preferencesSlice/preferencesSlice.ts (1)

56-56: LGTM!

The TrezorWallet feature flag follows the established pattern: added to the FeatureFlags type and initialized from configuration. Placement after LedgerWallet is consistent and logical.

Also applies to: 187-187

src/components/Modals/FiatRamps/views/FiatForm.tsx (1)

5-5: LGTM!

Extending skipDeviceDerivation to include Trezor aligns with the PR objective of reducing device prompts. This ensures Trezor behaves like Ledger/GridPlus by using cached pubKeys instead of triggering on-device derivation for address resolution in fiat ramp flows.

Also applies to: 88-88

src/context/WalletProvider/types.ts (1)

10-10: LGTM!

The type mappings wire TrezorAdapter into the AdaptersByKeyManager type system, following the established pattern for other wallet adapters. This is pure type wiring with no runtime impact.

Also applies to: 22-22

src/context/WalletProvider/config.ts (3)

308-312: LGTM!

The lazy-loaded TrezorMenu follows the established pattern for wallet menu components.


527-534: LGTM!

The TrezorConnectArgs type and manifest configuration appear correct for the Trezor Connect library API. The manifest includes required fields (appUrl, email, appName) and debug is appropriately set to false for production.

Also applies to: 553-561


497-501: The empty routes array is intentional—Trezor uses a new routing pattern.

Verification confirms: Trezor routes are wired in NewWalletViewsSwitch.tsx, which checks if (location.pathname.startsWith('/trezor')) return <TrezorRoutes />. This differs from legacy wallets (Ledger, KeepKey) which define routes in config.ts.

TrezorRoutes.tsx implements a simplified flow with a single catch-all route (<Route path='/*' />), handling only the connect/pair logic without separate success/failure/chains views. The Trezor config type explicitly omits the routes field, confirming this design decision. The empty array is the correct state for this new architecture.

@gomesalexandre gomesalexandre enabled auto-merge (squash) November 20, 2025 12:41
@gomesalexandre gomesalexandre merged commit e74cb94 into develop Nov 20, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_trezor branch November 20, 2025 12:48
@coderabbitai coderabbitai bot mentioned this pull request Nov 25, 2025
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.

Trezor Support

3 participants