Skip to content

feat: more wallet support for second-class chains#11396

Merged
NeOMakinG merged 19 commits intodevelopfrom
feat_second_class_mm
Dec 16, 2025
Merged

feat: more wallet support for second-class chains#11396
NeOMakinG merged 19 commits intodevelopfrom
feat_second_class_mm

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Dec 12, 2025

Description

Enables MetaMask, Ledger, Trezor, and WalletConnect V2 support for second-class EVM chains (HyperEVM, Monad, Plasma). Previously only Native wallet had support enabled.

Additional fixes:

  • Fixed Ledger app gate validation to use isEvmChainId() for all EVM chains
  • Fixed missing HyperEVM addresses in accountIdToLabel()
  • Added Gotcha 17 to chain-integration skill documentation

Depends on: shapeshift/hdwallet#769

Issue (if applicable)

Risk

Medium Risk - Requires hdwallet upgrade to 1.62.29

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

This affects wallet account derivation and transaction signing for HyperEVM, Monad, and Plasma chains across multiple wallet types (MetaMask, Ledger, Trezor, WalletConnect V2).

Testing

Engineering

⚠️ As for all things hardware wallets, ensure they're up-to-date when testing chains with those - ops has been burned by e.g TRON and SUI being seemingly borked

Prerequisites:

  • Install hdwallet 1.62.29 when published to npm done
  • Enable feature flags: VITE_FEATURE_HYPEREVM=true, VITE_FEATURE_MONAD=true, VITE_FEATURE_PLASMA=true (note, already enabled in dev, nothing to do here)

Test Cases:

  • Ledger: Test account derivation and transaction signing for HyperEVM, Monad, and Plasma
  • Trezor: Test account derivation and transaction signing for HyperEVM, Monad, and Plasma
  • MIPD Wallets (MetaMask/Rabby): Test account derivation and transaction signing for HyperEVM, Monad, and Plasma
  • WalletConnect V2: Test account derivation and transaction signing for HyperEVM, Monad, and Plasma
  • WalletConnect dApps: Worth testing WC dApp integrations for these chains, even though not exclusively brought by this PR, as we've never tested it before
  • Feature Flags OFF: Test with all three feature flags disabled - chains should NOT appear in any wallet's chain selection UI

Operations

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

Screenshots (if applicable)

MetaMask/Rabby (MIPD Wallets)

https://jam.dev/c/51e0580a-34e6-453f-ae67-f8a9a2ab87ed

Ledger

https://jam.dev/c/376d984e-d5cf-4e38-a6c3-7deecce57c88

Trezor

https://jam.dev/c/68de9989-a18e-4fc2-b387-6076ac686264

WalletConnect V2

https://jam.dev/c/0ec7b43d-e01e-4061-9004-4413511bcbfa

Feature Flag OFF Regression Test

https://jam.dev/c/8107541a-f2fe-424a-94c8-9fb8dd9107c0

WalletConnect dApps

https://jam.dev/c/89116565-8212-4dff-93f2-21e7aa5a08ed


Warnings

⚠️ MetaMask Desktop - HyperEVM Chain Addition: MetaMask Desktop requires manually enabling HyperEVM in "Additional Networks" from their Settings UI. If you try to let the app add the network via wallet_addEthereumChain, it will fail with a duplicate RPC URL error. This is not our issue - it's because MM already has HyperEVM in their network registry.

⚠️ MetaMask Mobile - WalletConnect Chain Addition: MetaMask Mobile fails when adding chains via WalletConnect. This is not a new issue but may be worth 1-2 hours of debugging to determine if this is something we can handle better or if it's a MetaMask Mobile limitation. In the interim, if testing WC with MM Mobile, first use the dApp browser (e.g., via Relay) to manually add all 3 chains before connecting via WalletConnect.

Summary by CodeRabbit

  • New Features

    • Broader Ledger support for EVM-compatible chains and explicit HyperEVM chain support.
    • Improved Tron Ledger address flow to ensure the Ledger app is ready before address retrieval.
  • Documentation

    • Expanded integration docs for second-class EVM and non-EVM chains.
    • Added a Gotcha about address label/display issues across wallet types with remediation steps.
  • Chores

    • Updated wallet package versions.

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

gomesalexandre and others added 12 commits December 12, 2025 11:57
Updates chain-integration skill documentation to reflect that MetaMask
supports HyperEVM, Monad, and Plasma chains. Also bumps hdwallet
dependencies to local verdaccio version for testing.

Changes:
- Updated SKILL.md to document MetaMask support for second-class EVM chains
- Added clarifying notes about Ledger/Trezor support
- Bumped all hdwallet-* packages to 1.62.29-second-class-mm.0

This allows MetaMask users to import and use accounts on HyperEVM,
Monad, and Plasma when feature flags are enabled.

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

Co-Authored-By: Claude <[email protected]>
Updates chain-integration skill documentation and hdwallet dependencies
to enable Ledger support for HyperEVM, Monad, and Plasma.

Changes:
- Updated SKILL.md to move Ledger to supported wallet list
- Updated documentation to reflect Ledger uses Ethereum app for all EVM chains
- Bumped all hdwallet-* packages to 1.62.29-second-class-mm.1

This allows Ledger users to import and use accounts on HyperEVM,
Monad, and Plasma when feature flags are enabled.

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

Co-Authored-By: Claude <[email protected]>
Fixes the Ledger "Open Gate" prompt appearing repeatedly for HyperEVM,
Monad, and Plasma by ensuring all EVM chains validate against the
Ethereum app instead of looking for chain-specific apps.

The issue was that `getCoin()` was returning chain-specific names like
"HyperEVM", "Monad", "Plasma" which Ledger's `validateCurrentApp()`
didn't recognize. All EVM chains use the same Ethereum Ledger app, so
they should all return "Ethereum" for validation.

Changes:
- Consolidated all EVM chain cases in getCoin() to return "Ethereum"
- Includes: Ethereum, Avalanche, Optimism, BSC, Polygon, Gnosis,
  Arbitrum, Arbitrum Nova, Base, Monad, HyperEVM, and Plasma

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

Co-Authored-By: Claude <[email protected]>
Refactors ledgerAppGate.ts to use isEvmChainId() instead of maintaining
an exhaustive case list of all EVM chains. This makes the code more
maintainable and automatically supports any new EVM chains added in the
future.

Benefits:
- No need to manually add each new EVM chain to the switch statements
- More maintainable - single source of truth for EVM chain detection
- Automatically works with future EVM chains (e.g., if we add Sei, Scroll, etc.)
- Cleaner, more readable code

Changes:
- Added isEvmChainId import from EvmBaseAdapter
- Refactored getLedgerAppName() to check isEvmChainId first
- Refactored getCoin() to check isEvmChainId first
- Removed 12+ explicit EVM chain cases from both functions

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

Co-Authored-By: Claude <[email protected]>
Fixes bug where HyperEVM account addresses were not displayed in:
- Ledger/Native account import UI (shows blank address)
- Send flow "from" address row (shows blank from address)

Root cause: accountIdToLabel() was missing hyperEvmChainId in its
switch statement. Monad and Plasma were present but HyperEVM was
missing, causing it to hit the default case and return empty string.

Changes:
- Added hyperEvmChainId import from @shapeshiftoss/caip
- Added hyperEvmChainId case to accountIdToLabel() switch statement

This makes HyperEVM addresses display correctly using middleEllipsis()
formatting, consistent with all other EVM chains.

Fixes: #11393 (partial - addresses Native wallet send flow issue)

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

Co-Authored-By: Claude <[email protected]>
Updates chain-integration skill documentation and hdwallet dependencies
to enable Trezor support for HyperEVM, Monad, and Plasma.

Changes:
- Updated SKILL.md to move Trezor to supported wallet list
- Updated documentation to reflect Trezor uses Ethereum app for all EVM chains
- Bumped all hdwallet-* packages to 1.62.29-second-class-mm.2

This allows Trezor users to import and use accounts on HyperEVM,
Monad, and Plasma when feature flags are enabled.

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

Co-Authored-By: Claude <[email protected]>
Updates chain-integration skill documentation and hdwallet dependencies
to enable WalletConnect V2 support for HyperEVM, Monad, and Plasma.

Changes:
- Updated SKILL.md to move WalletConnect V2 to supported wallet list
- Added note that WalletConnect V2 is chain-agnostic
- Bumped all hdwallet-* packages to 1.62.29-second-class-mm.3

This allows WalletConnect V2 users to connect wallets and use accounts
on HyperEVM, Monad, and Plasma when feature flags are enabled.

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

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

coderabbitai bot commented Dec 12, 2025

📝 Walkthrough

Walkthrough

Updates docs for second‑class EVM and non‑EVM guidance, bumps many @shapeshiftoss/hdwallet packages to 1.62.29, consolidates EVM handling in Ledger coin/app resolution, adds Tron and Sui mappings, restores HyperEVM account label handling, and adds a Ledger pre-check in the Tron adapter.

Changes

Cohort / File(s) Summary
Documentation
\.claude/skills/chain-integration/SKILL.md
Added sections for second‑class EVM and non‑EVM chains, reorganized flag guidance, and introduced Gotcha 17 describing the missing accountIdToLabel case and its fix.
Dependency bumps (hdwallet → 1.62.29)
package.json, packages/chain-adapters/package.json, packages/swapper/package.json
Updated multiple @shapeshiftoss/hdwallet-* package versions from 1.62.281.62.29 across root and package manifests.
Ledger app routing / coin mapping
packages/chain-adapters/src/utils/ledgerAppGate.ts
Added isEvmChainId checks to map all EVM chains to the Ethereum Ledger app and Ethereum coin; removed many explicit per‑chain Ethereum cases; added TronMainnet and SuiMainnet mappings.
Account label mapping
src/state/slices/portfolioSlice/utils/index.ts
Imported hyperEvmChainId and added a hyperEvmChainId case to accountIdToLabel to restore address label generation for HyperEVM accounts.
Tron Ledger pre-check
packages/chain-adapters/src/tron/TronChainAdapter.ts
Added a pre-check using verifyLedgerAppOpen before retrieving an address from Ledger.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review packages/chain-adapters/src/utils/ledgerAppGate.ts for any unintended remapping for non‑EVM chains (edge cases where coin/app selection previously differed).
  • Verify hyperEvmChainId is imported/used consistently with existing CAIP identifiers and label formatting in src/state/slices/portfolioSlice/utils/index.ts.
  • Confirm verifyLedgerAppOpen integration in packages/chain-adapters/src/tron/TronChainAdapter.ts preserves adapter error semantics and no public-interface changes occurred.
  • Quick sanity-check of dependency bumps for breaking changes in hdwallet v1.62.29 (API surface used here).

Possibly related PRs

Suggested reviewers

  • NeOMakinG
  • 0xApotheosis

Poem

🐰
I hopped through branches, nudged each chain,
Turned blank labels into names again.
Ledger learns EVM is one big den,
Docs and deps updated — now I grin. 🥕

Pre-merge checks and finishing touches

✅ 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 'feat: more wallet support for second-class chains' directly summarizes the main objective of enabling MetaMask, Ledger, Trezor, and WalletConnect V2 support for HyperEVM, Monad, and Plasma chains.
Linked Issues check ✅ Passed The PR addresses both linked issues: fixes the empty 'from' address on HyperEVM by adding hyperEvmChainId to accountIdToLabel (#11393), and enables wallet support for second-class chains via ledger app gate refactoring and dependency updates (#11371).
Out of Scope Changes check ✅ Passed All changes are directly scoped to the PR objectives: documentation updates for chain-integration skill, dependency version bumps for hdwallet packages, ledger app gate refactoring for EVM chain detection, and accountIdToLabel fix for HyperEVM address display.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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_second_class_mm

📜 Recent 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 0d17176 and b90d4bb.

📒 Files selected for processing (1)
  • packages/chain-adapters/src/utils/ledgerAppGate.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/chain-adapters/src/utils/ledgerAppGate.ts

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 marked this pull request as ready for review December 12, 2025 11:13
@gomesalexandre gomesalexandre requested review from a team as code owners December 12, 2025 11:13
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 104824e and 8a56626.

📒 Files selected for processing (6)
  • .claude/skills/chain-integration/SKILL.md (2 hunks)
  • package.json (1 hunks)
  • packages/chain-adapters/package.json (1 hunks)
  • packages/chain-adapters/src/utils/ledgerAppGate.ts (3 hunks)
  • packages/swapper/package.json (1 hunks)
  • src/state/slices/portfolioSlice/utils/index.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{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/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables 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/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
src/state/slices/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/state/slices/**/*.ts: Migrations are required when changing persisted state structure (see src/state/migrations/)
Export selectors from slice using inline selectors property

Files:

  • src/state/slices/portfolioSlice/utils/index.ts
src/state/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

src/state/**/*.{ts,tsx}: Use createDeepEqualOutputSelector from @/state/selector-utils for deep equality checks
Use createCachedSelector from re-reselect for parameterized selectors

Files:

  • src/state/slices/portfolioSlice/utils/index.ts
**/*.{js,jsx,ts,tsx}

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

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
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/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
🧠 Learnings (39)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:133-137
Timestamp: 2025-09-12T10:15:10.389Z
Learning: gomesalexandre has identified that EIP-712 domain chainId should be preferred over request context chainId for accuracy in WalletConnect dApps structured signing flows. The domain chainId from the parsed message is more specific and accurate than the general request context, especially for asset resolution and network-specific operations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:46-59
Timestamp: 2025-09-10T15:34:54.593Z
Learning: After extensive testing by gomesalexandre in PR #10458, dApps do not send EIP-712 domain.chainId as hex or bigint values in practice. The simple String(domain.chainId) conversion is sufficient for real-world usage in WalletConnect dApps structured signing.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:0-0
Timestamp: 2025-09-12T10:21:26.693Z
Learning: gomesalexandre explained that in WalletConnect V2, the request context chainId comes from params?.chainId following CAIP2 standards, making both the request params chainId and EIP-712 domain chainId equally reliable sources. He considers both approaches trustworthy ("both gucci") for WalletConnect dApps integration.
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: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.
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: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs

Applied to files:

  • src/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • packages/swapper/package.json
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.

Applied to files:

  • src/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/state/slices/**/*.ts : Migrations are required when changing persisted state structure (see `src/state/migrations/`)

Applied to files:

  • src/state/slices/portfolioSlice/utils/index.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/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • src/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-08-15T07:51:16.374Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10278
File: src/components/AssetHeader/hooks/useQuickBuy.ts:97-99
Timestamp: 2025-08-15T07:51:16.374Z
Learning: The selectPortfolioUserCurrencyBalanceByAssetId selector in src/state/slices/portfolioSlice/selectors.ts expects a filter object with an assetId property, not a raw AssetId string. The selector signature is (state: ReduxState, filter) where filter should have an assetId property. This pattern is consistent across portfolio selectors that use selectAssetIdParamFromFilter. Passing a filter object like { assetId: someAssetId } is the correct usage pattern.

Applied to files:

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

Applied to files:

  • src/state/slices/portfolioSlice/utils/index.ts
  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-12-04T22:57:50.850Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 11290
File: packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts:48-51
Timestamp: 2025-12-04T22:57:50.850Z
Learning: In packages/chain-adapters/src/**/*ChainAdapter.ts files, the getName() method uses the pattern `const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.XXX); return Object.keys(ChainAdapterDisplayName)[enumIndex]` to reverse-lookup the enum key from its value. This is the established pattern used consistently across almost all chain adapters (Bitcoin, Ethereum, Litecoin, Dogecoin, Polygon, Arbitrum, Cosmos, etc.) and should be preserved for consistency when adding new chain adapters.

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • packages/chain-adapters/package.json
  • .claude/skills/chain-integration/SKILL.md
  • package.json
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • packages/swapper/package.json
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

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

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • .claude/skills/chain-integration/SKILL.md
📚 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:

  • packages/chain-adapters/src/utils/ledgerAppGate.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/*/endpoints.ts : Reuse checkEvmSwapStatus utility for checking EVM swap status instead of implementing custom status checks

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • packages/swapper/package.json
📚 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:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • .claude/skills/chain-integration/SKILL.md
  • package.json
📚 Learning: 2025-09-12T10:21:26.693Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:0-0
Timestamp: 2025-09-12T10:21:26.693Z
Learning: gomesalexandre explained that in WalletConnect V2, the request context chainId comes from params?.chainId following CAIP2 standards, making both the request params chainId and EIP-712 domain chainId equally reliable sources. He considers both approaches trustworthy ("both gucci") for WalletConnect dApps integration.

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.ts
  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Each wallet has unique `walletId` (e.g., `metamask:0x123`, `ledger:ABC`)

Applied to files:

  • packages/chain-adapters/src/utils/ledgerAppGate.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:

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

Applied to files:

  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • package.json
📚 Learning: 2025-08-08T20:16:12.898Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10222
File: package.json:202-202
Timestamp: 2025-08-08T20:16:12.898Z
Learning: In shapeshift/web, the semver package must be included in dependencies (not devDependencies) because hdwallet packages have transient dependencies that require semver but don't ship it themselves. This ensures semver is available at runtime for hdwallet functionality.

Applied to files:

  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • package.json
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use camelCase for variable and function names in the Swapper system

Applied to files:

  • packages/swapper/package.json
📚 Learning: 2025-08-08T20:27:02.203Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10222
File: package.json:202-202
Timestamp: 2025-08-08T20:27:02.203Z
Learning: In shapeshift/web, while gomesalexandre generally prefers pinned dependencies for security, semver with a caret range (^7.7.2) is acceptable as an exception since it's already a transient dependency of many packages and is being made explicit for hdwallet support.

Applied to files:

  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • package.json
📚 Learning: 2025-12-09T21:07:22.474Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/utils/helpers.ts:3-3
Timestamp: 2025-12-09T21:07:22.474Z
Learning: In packages/swapper/src/swappers/CetusSwapper, mysten/sui types (SuiClient, Transaction) must be imported from the nested path within cetusprotocol/aggregator-sdk (e.g., 'cetusprotocol/aggregator-sdk/node_modules/mysten/sui/client') because the aggregator SDK bundles its own version of mysten/sui. Direct imports from 'mysten/sui' break at runtime even when specified in package.json.

Applied to files:

  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • package.json
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use PascalCase for types, interfaces, and enums in the Swapper system

Applied to files:

  • packages/swapper/package.json
📚 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/index.ts : Export unique functions and types from packages/swapper/src/index.ts only if needed for external consumption

Applied to files:

  • packages/swapper/package.json
📚 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:

  • packages/swapper/package.json
  • packages/chain-adapters/package.json
  • package.json
📚 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:

  • packages/chain-adapters/package.json
📚 Learning: 2025-08-07T11:20:05.201Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: package.json:0-0
Timestamp: 2025-08-07T11:20:05.201Z
Learning: gomesalexandre prefers pinned dependencies (exact versions without caret ranges) as a general security practice to prevent vulnerabilities from being introduced through automatic version bumps. He referenced the LedgerHQ/connect-kit vulnerability (GitHub issue #29) as an example of security risks from dependency updates.

Applied to files:

  • packages/chain-adapters/package.json
📚 Learning: 2025-09-10T15:34:54.593Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:46-59
Timestamp: 2025-09-10T15:34:54.593Z
Learning: After extensive testing by gomesalexandre in PR #10458, dApps do not send EIP-712 domain.chainId as hex or bigint values in practice. The simple String(domain.chainId) conversion is sufficient for real-world usage in WalletConnect dApps structured signing.

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 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:

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

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: To add a new feature flag: (1) Add to `FeatureFlags` type in `src/state/slices/preferencesSlice/preferencesSlice.ts`, (2) Add environment variable validation in `src/config.ts`, (3) Add to initial state in `preferencesSlice.ts`, (4) Add to test mock in `src/test/mocks/store.ts`, (5) Set appropriate values in `.env`, `.env.development`, and `.env.production`

Applied to files:

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

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 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:

  • .claude/skills/chain-integration/SKILL.md
  • package.json
📚 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:

  • .claude/skills/chain-integration/SKILL.md
📚 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:

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

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-08-21T22:16:55.203Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useFetchBasePortfolio.ts:33-35
Timestamp: 2025-08-21T22:16:55.203Z
Learning: In the ShapeShift web codebase Base portfolio management hack, the accountsById[accountId] check in upsertBasePortfolio serves as a security safeguard to ensure only user-associated accounts get balance updates, not just an existence check - this boundary should be maintained even during degraded Base state.

Applied to files:

  • .claude/skills/chain-integration/SKILL.md
📚 Learning: 2025-11-25T21:43:10.838Z
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.

Applied to files:

  • package.json
🧬 Code graph analysis (2)
src/state/slices/portfolioSlice/utils/index.ts (1)
packages/caip/src/constants.ts (1)
  • hyperEvmChainId (77-77)
packages/chain-adapters/src/utils/ledgerAppGate.ts (1)
packages/chain-adapters/src/evm/EvmBaseAdapter.ts (1)
  • isEvmChainId (89-93)
🔇 Additional comments (6)
packages/swapper/package.json (1)

42-42: Bump is fine; verify swapper resolves the same hdwallet-core as the app.
Since this is an external dependency change, please confirm the workspace resolves a single @shapeshiftoss/[email protected] and the lockfile matches.

src/state/slices/portfolioSlice/utils/index.ts (2)

1-34: Importing hyperEvmChainId from CAIP is the right fix point for label mapping.


81-126: HyperEVM now renders a non-empty account label (fixes blank “from”/address UI).
Adding case hyperEvmChainId: alongside other EVM-like chains ensures accountIdToLabel() won’t hit default and return ''.

#!/bin/bash
set -euo pipefail

echo "== Find other chainId switches that might also need HyperEVM/Monad/Plasma =="
rg -n --type=ts --type=tsx -S 'switch\s*\(\s*chainId\b|\bcase\s+hyperEvmChainId\b|\bcase\s+monadChainId\b|\bcase\s+plasmaChainId\b' src packages

echo
echo "== Specifically check isAssetSupportedByWallet() (if present) includes new chainIds where required =="
rg -n --type=ts --type=tsx -S 'export const isAssetSupportedByWallet|case\s+hyperEvmChainId|case\s+monadChainId|case\s+plasmaChainId' src/state/slices/portfolioSlice/utils/index.ts
.claude/skills/chain-integration/SKILL.md (1)

1750-1776: Gotcha 17 is accurate and maps to the real fix; ensure it’s not duplicated in the doc.

packages/chain-adapters/src/utils/ledgerAppGate.ts (1)

8-47: Good consolidation: EVM chains consistently map to Ethereum app/coin.

The refactor correctly removes enum duplication across both getLedgerAppName() and getCoin(). The evmChainIds list includes all new second-class EVM networks (Monad, HyperEVM, Plasma), so isEvmChainId() will properly identify them for Ledger app routing. No leftover explicit EVM cases remain in the file.

package.json (1)

103-120: Coordinated hdwallet- bump to 1.62.29 is consistent across all packages; lockfile updated.*

All @shapeshiftoss/hdwallet-* packages in the root and workspace dependencies are uniformly pinned to 1.62.29 with no partial upgrades. The yarn.lock has been regenerated with the new versions. The semver dependency remains in place, which is correct for hdwallet runtime requirements.

gomesalexandre and others added 4 commits December 16, 2025 03:22
Adds `verifyLedgerAppOpen` call to Tron chain adapter's `getAddress` method to prompt users to open the Tron app on their Ledger device before attempting to derive addresses. This matches the pattern used in other chain adapters like Solana.

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

Co-Authored-By: Claude <[email protected]>
Adds Sui to the list of supported chains in the ledger app gate validation functions. This ensures that when users try to interact with Sui using a Ledger hardware wallet, the app will properly prompt them to open the Sui app on their device.

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

Co-Authored-By: Claude <[email protected]>
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.

Ledger

image Signed multiple TXs (swap and sends), seems to work as intended!

Trezor

image

Seems to be working fine as well!

MM

image I've been able to sign TXs as well

WC

Looks like all my accounts are here, using MM mobile but through WC, been able to swap!

WC Dapp

image I've been able to connect and swap, I had an error on relay side when submitting the swap but the swap went through, not sure if this is a us issue btw considering the tests you've done too on your side

@NeOMakinG NeOMakinG enabled auto-merge (squash) December 16, 2025 10:27
@NeOMakinG NeOMakinG merged commit 4c48f47 into develop Dec 16, 2025
4 checks passed
@NeOMakinG NeOMakinG deleted the feat_second_class_mm branch December 16, 2025 10:36
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.

HyperEVM - empty from when sending feat: Enable MetaMask, WalletConnect, Coinbase, Ledger, and Trezor support for second-class EVM chains

2 participants