Skip to content

fix: second-class evm adapter tokens fetching - #11550

Merged
gomesalexandre merged 1 commit into
developfrom
fix_hyperevm_tokens
Dec 30, 2025
Merged

fix: second-class evm adapter tokens fetching#11550
gomesalexandre merged 1 commit into
developfrom
fix_hyperevm_tokens

Conversation

@gomesalexandre

@gomesalexandre gomesalexandre commented Dec 30, 2025

Copy link
Copy Markdown
Contributor

Description

Fix race condition where second-class EVM chain adapters (HyperEVM, Monad, Plasma) were created with an empty token list because the asset service hadn't loaded yet. Changed from static knownTokens array to a getKnownTokens() getter function that fetches tokens dynamically at call time.

Issue (if applicable)

closes #11549

Risk

Low - only affects second-class EVM chains token balance fetching. No changes to transaction handling or core functionality.

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

HyperEVM, Monad, and Plasma token balance display.

Testing

Engineering

  • tokens for second-class EVM chains should be happy again same like in prod

Operations

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

Screenshots (if applicable)

  • this diff
Screenshot 2025-12-30 at 19 18 51 Screenshot 2025-12-30 at 19 19 10
  • prod
Screenshot 2025-12-30 at 19 21 05
  • develop
Screenshot 2025-12-30 at 19 22 15 Screenshot 2025-12-30 at 19 22 26

Summary by CodeRabbit

  • Refactor
    • Updated token retrieval mechanisms across chain adapters to use dynamic sourcing instead of static configurations, improving flexibility in how known tokens are provided to the system.

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

The SecondClassEvmAdapter was using a static knownTokens array set at
construction time. Due to initialization order (PluginProvider creates
adapters before AppProvider loads assets), the token list was always
empty.

Changed to a getter function pattern so tokens are fetched from the
asset service at call time, ensuring they're always available after
the app initializes.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gomesalexandre
gomesalexandre requested a review from a team as a code owner December 30, 2025 18:22
@coderabbitai

coderabbitai Bot commented Dec 30, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR converts token provisioning across EVM chain adapters from static properties to lazy-evaluated getter functions, affecting the SecondClassEvmAdapter core class and all dependent chain implementations and plugin initializers.

Changes

Cohort / File(s) Summary
Core SecondClassEvmAdapter
packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
Replaced public knownTokens: TokenInfo[] property with protected getKnownTokens: () => TokenInfo[] getter function. Updated getAccount() to invoke getter and store result locally, and parseTx() to retrieve tokens via getter instead of direct property access. Constructor now accepts and assigns getKnownTokens from args.
EVM Chain Adapter Signature Updates
packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts, packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts, packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
Updated ChainAdapterArgs type signatures from optional knownTokens?: TokenInfo[] to required getKnownTokens: () => TokenInfo[]. Modified super() constructor calls to pass getKnownTokens: args.getKnownTokens instead of knownTokens: args.knownTokens ?? [].
Plugin Initializers
src/plugins/hyperevm/index.tsx, src/plugins/monad/index.tsx, src/plugins/plasma/index.tsx
Wrapped inline token list construction logic into getKnownTokens() functions. Updated ChainAdapter instantiation to pass getter function instead of precomputed token array.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

capy

Suggested reviewers

  • premiumjibles
  • NeOMakinG

Poem

🐰 A getter hops where static lay before,
Tokens now fetch, no more a frozen store,
Lazy evaluation saves the day,
Second-class chains get their tokens at play! ✨

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 'fix: second-class evm adapter tokens fetching' is directly related to the main change—replacing static knownTokens with a dynamic getter to fix token fetching for second-class EVM chains.
Linked Issues check ✅ Passed The pull request implements the required fix from issue #11549 by converting static knownTokens arrays to dynamic getKnownTokens() getters across all second-class EVM adapters, resolving the race condition and ensuring tokens are fetched correctly.
Out of Scope Changes check ✅ Passed All changes are scoped to converting knownTokens from static arrays to dynamic getter functions across SecondClassEvmAdapter and its subclasses (HyperEVM, Monad, Plasma), with corresponding plugin updates—all directly addressing the linked issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix_hyperevm_tokens

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0128e74 and 26f6061.

📒 Files selected for processing (7)
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/hyperevm/index.tsx
  • src/plugins/monad/index.tsx
  • src/plugins/plasma/index.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/plugins/hyperevm/index.tsx
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.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/plugins/hyperevm/index.tsx
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
**/*.{tsx,jsx}

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

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

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

Files:

  • src/plugins/hyperevm/index.tsx
  • src/plugins/plasma/index.tsx
  • src/plugins/monad/index.tsx
**/*.{js,jsx,ts,tsx}

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

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

Files:

  • src/plugins/hyperevm/index.tsx
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
**/*.{jsx,tsx}

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

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

Files:

  • src/plugins/hyperevm/index.tsx
  • src/plugins/plasma/index.tsx
  • src/plugins/monad/index.tsx
**/*.tsx

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

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

Files:

  • src/plugins/hyperevm/index.tsx
  • src/plugins/plasma/index.tsx
  • src/plugins/monad/index.tsx
🧠 Learnings (15)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: 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.
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: 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.
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.
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-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:

  • src/plugins/hyperevm/index.tsx
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
📚 Learning: 2025-12-17T14:50:01.629Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.

Applied to files:

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

Applied to files:

  • src/plugins/hyperevm/index.tsx
  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.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/plugins/hyperevm/index.tsx
  • src/plugins/plasma/index.tsx
  • src/plugins/monad/index.tsx
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.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 : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts
  • src/plugins/monad/index.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:

  • packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts
  • src/plugins/plasma/index.tsx
  • packages/chain-adapters/src/evm/monad/MonadChainAdapter.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 : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
🧬 Code graph analysis (3)
packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts (4)
packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts (1)
  • TokenInfo (33-39)
packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (1)
  • TokenInfo (57-57)
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (1)
  • TokenInfo (57-57)
packages/chain-adapters/src/evm/index.ts (1)
  • TokenInfo (4-4)
packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (1)
packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts (1)
  • TokenInfo (33-39)
src/plugins/plasma/index.tsx (5)
src/lib/asset-service/service/AssetService.ts (1)
  • getAssetService (217-222)
packages/caip/src/assetId/assetId.ts (1)
  • fromAssetId (140-172)
packages/caip/src/constants.ts (1)
  • plasmaChainId (78-78)
packages/utils/src/assetData/baseAssets.ts (1)
  • plasma (357-373)
src/config.ts (1)
  • getConfig (239-241)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Call / Static
🔇 Additional comments (9)
src/plugins/plasma/index.tsx (1)

22-40: LGTM! Lazy token fetching correctly addresses the race condition.

The getKnownTokens getter ensures tokens are fetched from assetService at call time rather than at adapter construction, fixing the initialization order issue. The implementation correctly filters for Plasma chain ERC20 tokens and maps them to the expected TokenInfo shape.

src/plugins/monad/index.tsx (1)

22-40: LGTM! Consistent with the plasma plugin implementation.

The lazy token fetching pattern is correctly applied using monadChainId for filtering Monad chain tokens.

packages/chain-adapters/src/evm/hyperevm/HyperEvmChainAdapter.ts (1)

13-16: LGTM! Clean API surface change from optional array to required getter.

The getKnownTokens property is now required (no ?), which is appropriate since all callers in this PR have been updated to provide the getter function.

packages/chain-adapters/src/evm/plasma/PlasmaChainAdapter.ts (1)

13-16: LGTM! Consistent with HyperEVM adapter pattern.

Also applies to: 29-37

packages/chain-adapters/src/evm/monad/MonadChainAdapter.ts (1)

13-16: LGTM! Consistent with other second-class EVM adapter patterns.

Also applies to: 29-37

src/plugins/hyperevm/index.tsx (1)

22-40: LGTM! Completes the consistent pattern across all second-class EVM plugins.

packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts (3)

47-48: LGTM! Core fix for the race condition.

The shift from storing a static knownTokens array to a getKnownTokens getter function ensures tokens are fetched from the asset service at usage time rather than construction time. This correctly addresses the initialization order issue.

Also applies to: 54-54, 80-80


103-106: LGTM! Lazy evaluation at usage point.

Calling this.getKnownTokens() here ensures the token list is fetched when balances are actually needed, guaranteeing the asset service is loaded.


413-418: LGTM! Consistent lazy evaluation in transaction parsing.

The parseTx method now correctly fetches tokens via the getter for token transfer lookups.


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

Copy link
Copy Markdown
Contributor Author

Going to yeet once CI passes to unrug release.

@gomesalexandre
gomesalexandre enabled auto-merge (squash) December 30, 2025 19:05
@gomesalexandre
gomesalexandre merged commit f83bd2f into develop Dec 30, 2025
4 checks passed
@gomesalexandre
gomesalexandre deleted the fix_hyperevm_tokens branch December 30, 2025 19:06
@coderabbitai coderabbitai Bot mentioned this pull request Jan 5, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Second class EVM chains - tokens not fetched

1 participant