Skip to content

feat: integrate Ethereal (5064014) as second-class Relay chain#11940

Merged
gomesalexandre merged 29 commits intodevelopfrom
feat/integrate-ethereal-relay
Feb 25, 2026
Merged

feat: integrate Ethereal (5064014) as second-class Relay chain#11940
gomesalexandre merged 29 commits intodevelopfrom
feat/integrate-ethereal-relay

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Feb 18, 2026

Description

Add support for Ethereal (EVM chain, chainId 5064014) as a second-class citizen. Ethereal is an Ethena-powered chain that uses USDe (a stablecoin) as its native gas token.

This is PR 16 of 17 in a sequential chain integration series. These PRs must be reviewed and merged in order, as each builds on the previous one (stacked branches).

PR merge order:

  1. Mantle (feat: integrate Mantle (chainId 5000) as second-class EVM chain #11905)
  2. Cronos (feat: integrate Cronos (chainId 25) as second-class EVM chain #11910)
  3. Sonic (feat: integrate Sonic (eip155:146) as second-class EVM chain #11923)
  4. Unichain (feat: integrate Unichain (eip155:130) as second-class citizen via Relay #11924)
  5. BOB (feat: integrate BOB (eip155:60808) as second-class citizen #11925)
  6. Mode (feat: integrate Mode (eip155:34443) as second-class citizen #11926)
  7. Soneium (feat: integrate Soneium (chainId: 1868) via Relay #11930)
  8. Hemi (feat: integrate Hemi (chainId: 43111) via Relay #11931)
  9. World Chain (feat: integrate World Chain (480) as second-class Relay chain #11932)
  10. Blast (feat: integrate Blast (81457) as second-class Relay chain #11933)
  11. zkSync Era (feat: integrate zkSync Era (324) as second-class Relay chain #11934)
  12. Story (feat: integrate Story (1514) as second-class Relay chain #11936)
  13. Plume (feat: integrate Plume (98866) as second-class Relay chain #11937)
  14. Flow EVM (feat: integrate Flow EVM (747) as second-class Relay chain #11938)
  15. Celo (feat: integrate Celo (42220) as second-class Relay chain #11939)
  16. Ethereal (feat: integrate Ethereal (5064014) as second-class Relay chain #11940) ← this PR

Note: Linea (#11922) is already in develop.

Note: Ethereal is not yet listed on CoinGecko, so price feeds are not available. It also requires a custom viem chain definition since it's not in the viem/chains package.

Implements: CAIP constants, chain adapter (SecondClassEvmAdapter), plugin, feature flag, Relay swapper mapping, HDWallet support flags, CSP headers, asset generation script, custom viem chain definition, ethers provider configuration, Zerion portfolio tracking, and all required shared-file entries.

Issue (if applicable)

Part of #11902

Risk

Low - All changes are behind the Ethereal feature flag (VITE_FEATURE_ETHEREAL), disabled by default in production.

No new on-chain transactions or contract interactions. Standard EVM chain support using existing SecondClassEvmAdapter pattern.

No protocols, transaction types, wallets or contract interactions are affected until the feature flag is enabled.

Testing

Engineering

  1. Set VITE_FEATURE_ETHEREAL=true in .env.development
  2. Run yarn dev
  3. Verify Ethereal appears in chain selector
  4. Verify native USDe balance loads
  5. Verify Relay swap routes include Ethereal
  6. Run yarn lint — passes with 0 errors
  7. Run yarn type-check — verify no new type errors

Operations

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

Screenshots (if applicable)

N/A - Behind feature flag, no visual changes until enabled.

Summary by CodeRabbit

New Features

  • Added support for Ethereal blockchain integration and asset trading.
  • Expanded multi-chain support including Celo, Flow EVM, Plume, World Chain, and Story networks.
  • Enhanced swap widget with improved cross-chain transaction handling.
  • Added wallet compatibility across newly supported blockchains.

Bug Fixes

  • Corrected Celo and Flow EVM node endpoint configurations.

Lines changed: +9/-7

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Ethereal (chainId 5064014, USDe native asset) as a new second-class EVM chain alongside renaming Flow EVM environment variables (VITE_FLOWEVM → VITE_FLOW_EVM). Introduces chain-specific infrastructure including adapters, viem clients, CSP headers, asset definitions, wallet support flags across all HDWallet implementations, and feature-flagged plugin registration. Updates environment and configuration files, type definitions, and related utility functions across the codebase. Additionally rewrites the SwapWidget component for multi-chain swap execution with cross-chain wallet switching support.

Changes

Cohort / File(s) Summary
Chain Definition & Metadata
.beads/ss-dx5.12.json, .beads/ss-dx5.15.json, .beads/ss-dx5.17.json
Added three new integration task entries for Ethereal, Plume, and Celo with comprehensive metadata, dependencies, and cross-referenced epic linkage to ss-dx5 parent epic.
Environment & Configuration
.env, .env.development, src/vite-env.d.ts, src/config.ts
Renamed VITE_FLOWEVM→VITE_FLOW_EVM, added VITE_ETHEREAL_NODE_URL/VITE_FEATURE_ETHEREAL, updated node URLs for multiple chains (Celo, Worldchain, Plume), and expanded feature flag declarations.
CSP Headers & Chain Exports
headers/csps/chains/ethereal.ts, headers/csps/chains/flowEvm.ts, headers/csps/index.ts
Created new Ethereal CSP module, updated Flow EVM to use renamed env var, and reordered CSP imports to include Ethereal after dogecoin.
CAIP Constants & Type Definitions
packages/caip/src/adapters/coingecko/index.ts, packages/caip/src/constants.ts, packages/types/src/base.ts, packages/types/src/zerion.ts
Added EtherealMainnet (eip155:5064014) and etherealAssetId constants; reordered Plume/FlowEvm in enums; added Ethereal to fee asset lists, chain references, and Zerion chain mappings.
EVM Chain Adapter Infrastructure
packages/chain-adapters/src/evm/EvmBaseAdapter.ts, packages/chain-adapters/src/evm/ethereal/EtherealChainAdapter.ts, packages/chain-adapters/src/evm/ethereal/index.ts, packages/chain-adapters/src/evm/index.ts
Implemented new EtherealChainAdapter extending SecondClassEvmAdapter with Ethereal-specific configuration (rootBip44Params, assetId, chainId mappings); exported through barrel and evm namespace; added Ethereal to evmChainIds list.
Secondary EVM Adapters & Type Maps
packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts, packages/chain-adapters/src/types.ts, packages/chain-adapters/src/evm/mantle/MantleChainAdapter.ts
Extended SecondClassEvmAdapter for Plume wrapped contracts and Celo fallback ERC20 parsing; added EtherealMainnet to all chain-specific type maps (ChainSpecificAccount, ChainSpecificFeeData, etc.) and reordered FlowEvmMainnet; removed isMantleChainAdapter export.
Contract & Viem Client Configuration
packages/contracts/src/ethersProviderSingleton.ts, packages/contracts/src/viemClient.ts
Added EtherealMainnet RPC mapping; defined ethereal Viem chain with USDe currency and explorer; created viemEtherealClient with fallback transport; updated viemClientByChainId and viemNetworkIdByChainId mappings; renamed FlowEvm env var reference.
HDWallet Capability Flags
packages/hdwallet-coinbase/src/coinbase.ts, packages/hdwallet-core/src/ethereum.ts, packages/hdwallet-core/src/wallet.ts, packages/hdwallet-gridplus/src/gridplus.ts, packages/hdwallet-keepkey/src/keepkey.ts, packages/hdwallet-ledger/src/ledger.ts, packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts, packages/hdwallet-native/src/ethereum.ts, packages/hdwallet-phantom/src/phantom.ts, packages/hdwallet-trezor/src/trezor.ts, packages/hdwallet-vultisig/src/vultisig.ts, packages/hdwallet-walletconnectv2/src/walletconnectV2.ts
Added _supportsEthereal, _supportsCelo, _supportsFlowEvm capability flags across all HDWallet implementations; repositioned _supportsPlume declarations; added supportsEthereal type guard in wallet.ts.
Asset Data & Utilities
packages/utils/src/assetData/baseAssets.ts, packages/utils/src/assetData/getBaseAsset.ts, packages/utils/src/chainIdToFeeAssetId.ts, packages/utils/src/getAssetNamespaceFromChainId.ts, packages/utils/src/getChainShortName.ts, packages/utils/src/getNativeFeeAssetReference.ts, scripts/generateAssetData/ethereal/index.ts, scripts/generateAssetData/generateAssetData.ts
Added Ethereal asset export with USDe details, explorer links, and icon; updated fee asset mappings for EtherealMainnet; added short name 'ETH_E'; created generateAssetData script module for Ethereal; updated asset generation pipeline.
Swapper Relay Integration
packages/swapper/src/swappers/RelaySwapper/constant.ts, packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
Added etherealChainId to Relay chainId mappings; updated FlowEvm to use flowMainnet.id; added worldChainChainId and storyChainId mappings; updated relayTokenToAssetId to map EtherealMainnet to ASSET_REFERENCE.Ethereal.
Swap Widget Rewrite
packages/swap-widget/src/components/SwapWidget.tsx
Substantially rewrote component from internal state-driven to multi-chain/multi-protocol framework (EVM, UTXO, Solana); added cross-chain wallet switching via VIEM_CHAINS_BY_ID, chain-aware execution flows (executeEvmSwap, executeUtxoSwap, executeSolanaSwap), multi-chain balance handling, and transaction status UI; preserved public SwapWidget export.
Plugin System
src/plugins/ethereal/index.tsx, src/plugins/flowEvm/index.tsx, src/plugins/activePlugins.ts
Created new Ethereal plugin registration with feature-flag gating and chain adapter factory; updated FlowEvm plugin to use renamed VITE_FLOW_EVM_NODE_URL; added Ethereal to activePlugins array and reordered Celo.
Configuration & Feature Flags
src/context/WalletProvider/WalletConnectV2/config.ts, src/state/slices/preferencesSlice/preferencesSlice.ts, src/test/mocks/store.ts
Expanded WalletConnectV2 with Ethereal and 13 additional chain RPC mappings (Mantle, Cronos, Sonic, etc.); added Ethereal to optional chains; added Ethereal feature flag to FeatureFlags type; updated test mock store with Ethereal flag.
Chain & Asset Filtering
src/constants/chains.ts, src/context/PluginProvider/PluginProvider.tsx, src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts, src/lib/account/evm.ts, src/lib/asset-service/service/AssetService.ts, src/lib/coingecko/utils.ts
Added EtherealMainnet and CeloMainnet gating via feature flags; updated wallet support checks with Ethereal/Plume capability guards; extended asset filtering logic for Ethereal and reorganized Celo/FlowEvm checks.
UI & State Components
src/pages/Markets/components/MarketsRow.tsx, src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx, src/state/slices/opportunitiesSlice/mappings.ts, src/state/slices/portfolioSlice/utils/index.ts
Added Ethereal feature flag checks and chain gating in markets filtering; extended popular assets query to conditionally include Ethereal, Celo, FlowEvm, and Plume; added EtherealMainnet to opportunities and portfolio chain mappings with supportsEthereal/supportsPlume checks.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

The scope is substantial with heterogeneous changes: new EtherealChainAdapter implementation, comprehensive type/constant updates across CAIP and contract packages, repeated capability flag additions across 12 HDWallet implementations (moderate homogeneity reduces per-file review), environment variable consolidation, and a major SwapWidget rewrite. The integration pattern is applied consistently but the variety of file types (adapters, types, configs, plugins, hooks, state) and the density of the swap widget logic necessitate careful review.

Possibly related PRs

  • feat: integrate BOB (eip155:60808) as second-class citizen #11925 — Parallel integration of a new EVM second-class chain (BOB) with near-identical changes across chain adapters, viem clients, CAIP constants, asset data, CSP headers, hdwallet supports, and feature flag wiring.
  • feat: hyperEVM #11262 — Similar code-level pattern for adding a new EVM chain (HyperEVM) modifying the same subsystems (chain constants, adapters, viem/ethers clients, plugin registrations, wallet support guards, and CSP configuration).
  • fix: cleanup swap widget #11865 — Overlapping changes to the swap-widget component for multi-chain swap UI/logic and execution paths with related transaction handling and cross-chain support.

Poem

🐰 Ethereal dreams now flow through chains so bright,
With adapters wired and vaults alight,
From Plume to Celo, each thread now spun,
The SwapWidget dances—multi-chains as one! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: integrating Ethereal as a second-class Relay chain. It is specific, concise, and clearly conveys the primary change.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/integrate-ethereal-relay

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 and others added 3 commits February 23, 2026 18:25
…ereal-relay

# Conflicts:
#	.claude/contracts/second-class-evm-chain.md
#	.env
#	.env.development
#	headers/csps/chains/flowEvm.ts
#	headers/csps/index.ts
#	packages/caip/src/adapters/coincap/generated/eip155_1/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_10/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_137/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_42161/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_43114/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_56/adapter.json
#	packages/caip/src/adapters/coincap/generated/eip155_8453/adapter.json
#	packages/caip/src/adapters/coincap/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_1/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_130/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_137/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_146/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_1514/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_1868/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_25/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_324/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_34443/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_42161/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_42220/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_43111/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_43114/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_480/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_5000/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_56/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_59144/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_60808/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_747/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_80094/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_81457/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_8453/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_98866/adapter.json
#	packages/caip/src/adapters/coingecko/generated/eip155_999/adapter.json
#	packages/caip/src/adapters/coingecko/generated/index.ts
#	packages/caip/src/adapters/coingecko/generated/solana_5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/adapter.json
#	packages/caip/src/adapters/coingecko/generated/sui_35834a8a/adapter.json
#	packages/caip/src/adapters/coingecko/index.test.ts
#	packages/caip/src/adapters/coingecko/index.ts
#	packages/caip/src/adapters/coingecko/utils.test.ts
#	packages/caip/src/adapters/coingecko/utils.ts
#	packages/caip/src/constants.ts
#	packages/chain-adapters/src/evm/EvmBaseAdapter.ts
#	packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
#	packages/chain-adapters/src/evm/index.ts
#	packages/chain-adapters/src/evm/mantle/MantleChainAdapter.ts
#	packages/chain-adapters/src/types.ts
#	packages/contracts/src/ethersProviderSingleton.ts
#	packages/contracts/src/viemClient.ts
#	packages/hdwallet-coinbase/src/coinbase.ts
#	packages/hdwallet-core/src/ethereum.ts
#	packages/hdwallet-core/src/wallet.ts
#	packages/hdwallet-gridplus/src/gridplus.ts
#	packages/hdwallet-keepkey/src/keepkey.ts
#	packages/hdwallet-ledger/src/ledger.ts
#	packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts
#	packages/hdwallet-native/src/ethereum.ts
#	packages/hdwallet-phantom/src/phantom.ts
#	packages/hdwallet-trezor/src/trezor.ts
#	packages/hdwallet-vultisig/src/vultisig.ts
#	packages/hdwallet-walletconnectv2/src/walletconnectV2.ts
#	packages/swap-widget/src/components/SwapWidget.tsx
#	packages/swapper/src/swappers/AcrossSwapper/constant.ts
#	packages/swapper/src/swappers/RelaySwapper/constant.ts
#	packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
#	packages/types/src/base.ts
#	packages/types/src/zerion.ts
#	packages/utils/src/assetData/baseAssets.ts
#	packages/utils/src/assetData/getBaseAsset.ts
#	packages/utils/src/chainIdToFeeAssetId.ts
#	packages/utils/src/getAssetNamespaceFromChainId.ts
#	packages/utils/src/getChainShortName.ts
#	packages/utils/src/getNativeFeeAssetReference.ts
#	public/generated/asset-manifest.json
#	public/generated/asset-manifest.json.br
#	public/generated/asset-manifest.json.gz
#	public/generated/generatedAssetData.json
#	public/generated/generatedAssetData.json.br
#	public/generated/generatedAssetData.json.gz
#	public/generated/relatedAssetIndex.json
#	public/generated/relatedAssetIndex.json.br
#	public/generated/relatedAssetIndex.json.gz
#	scripts/generateAssetData/coingecko.ts
#	scripts/generateAssetData/generateAssetData.ts
#	scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts
#	scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts
#	src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
#	src/config.ts
#	src/constants/chains.ts
#	src/context/PluginProvider/PluginProvider.tsx
#	src/context/WalletProvider/WalletConnectV2/config.ts
#	src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
#	src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts
#	src/lib/account/evm.ts
#	src/lib/asset-service/service/AssetService.ts
#	src/lib/coingecko/utils.ts
#	src/lib/market-service/coingecko/coingecko.test.ts
#	src/pages/Markets/components/MarketsRow.tsx
#	src/plugins/activePlugins.ts
#	src/plugins/flowEvm/index.tsx
#	src/state/migrations/index.ts
#	src/state/slices/opportunitiesSlice/mappings.ts
#	src/state/slices/portfolioSlice/utils/index.ts
#	src/state/slices/preferencesSlice/preferencesSlice.ts
#	src/test/mocks/store.ts
#	src/vite-env.d.ts
…tion

- reset generated files to develop then regen ethereal
- fix broken try/catch blocks in coingecko utils.ts (7 chains)
- fix broken Object.freeze closings in baseAssets.ts
- fix broken switch cases in coingecko.ts
- fix broken toAssetId closings in index.test.ts
- add etherealChainId export to generate:chain module
- add ethereal export to baseAssets.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre marked this pull request as ready for review February 23, 2026 17:40
@gomesalexandre gomesalexandre requested a review from a team as a code owner February 23, 2026 17:40
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: 9

Caution

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

⚠️ Outside diff range comments (4)
scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts (1)

53-84: ⚠️ Potential issue | 🔴 Critical

Data inconsistency: manualRelatedAssetIndex differs between full and per-chain generation functions — per-chain updates will not include manual links for blast, bob, cronos, hemi, mode, soneium, sonic, unichain, worldchain, zkSyncEra.

The manualRelatedAssetIndex in generateChainRelatedAssetIndex.ts contains only 8 assets, while the same index in generateRelatedAssetIndex/generateRelatedAssetIndex.ts contains 20 assets (includes zkSyncEraAssetId, blastAssetId, worldChainAssetId, hemiAssetId, unichainAssetId, bobAssetId, modeAssetId, soneiumAssetId). Since generateChainRelatedAssetIndex() is called during per-chain updates via yarn generate:chain, incremental regeneration of ETH or other chains will not include manual related asset links for the missing chains, even if the full generation includes them. Either synchronize both files or verify this is intentional and document the split strategy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts`
around lines 53 - 84, The manualRelatedAssetIndex defined in
generateChainRelatedAssetIndex.ts is missing many entries present in the full
generateRelatedAssetIndex (causing per-chain runs to omit manual links); update
manualRelatedAssetIndex in generateChainRelatedAssetIndex (or refactor to
import/share the single source) to include the same asset keys (e.g.,
zkSyncEraAssetId, blastAssetId, worldChainAssetId, hemiAssetId, unichainAssetId,
bobAssetId, modeAssetId, soneiumAssetId and any others present in
generateRelatedAssetIndex/generateRelatedAssetIndex.ts) so per-chain generation
via generateChainRelatedAssetIndex() matches the full generation, or
alternatively add a comment documenting the intentional split and which keys are
omitted.
packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts (1)

164-195: ⚠️ Potential issue | 🔴 Critical

Critical: Nine switch cases have incomplete return objects — missing assetNamespace and closing braces.

Lines 164–190 contain nine consecutive case blocks where each return { is never closed and assetNamespace: ASSET_NAMESPACE.slip44 is missing. This is a syntax error that will fail TypeScript compilation.

Affected cases: EtherealMainnet, CeloMainnet, FlowEvmMainnet, PlumeMainnet, StoryMainnet, ZkSyncEraMainnet, BlastMainnet, WorldChainMainnet, HemiMainnet.

🐛 Proposed fix — restore closing braces and assetNamespace for all affected cases
       case CHAIN_REFERENCE.EtherealMainnet:
         return {
           assetReference: ASSET_REFERENCE.Ethereal,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.CeloMainnet:
         return {
           assetReference: ASSET_REFERENCE.Celo,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.FlowEvmMainnet:
         return {
           assetReference: ASSET_REFERENCE.FlowEvm,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.PlumeMainnet:
         return {
           assetReference: ASSET_REFERENCE.Plume,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.StoryMainnet:
         return {
           assetReference: ASSET_REFERENCE.Story,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.ZkSyncEraMainnet:
         return {
           assetReference: ASSET_REFERENCE.ZkSyncEra,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.BlastMainnet:
         return {
           assetReference: ASSET_REFERENCE.Blast,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.WorldChainMainnet:
         return {
           assetReference: ASSET_REFERENCE.WorldChain,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
       case CHAIN_REFERENCE.HemiMainnet:
         return {
           assetReference: ASSET_REFERENCE.Hemi,
+          assetNamespace: ASSET_NAMESPACE.slip44,
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts`
around lines 164 - 195, The switch cases inside relayTokenToAssetId that handle
CHAIN_REFERENCE.EtherealMainnet, CeloMainnet, FlowEvmMainnet, PlumeMainnet,
StoryMainnet, ZkSyncEraMainnet, BlastMainnet, WorldChainMainnet, and HemiMainnet
return unterminated objects and omit assetNamespace; fix each of those case
blocks in relayTokenToAssetId by closing the returned object and adding
assetNamespace: ASSET_NAMESPACE.slip44 (e.g., return { assetReference:
ASSET_REFERENCE.Ethereal, assetNamespace: ASSET_NAMESPACE.slip44 };), ensuring
each case has the proper closing brace and semicolon so TypeScript compiles.
scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts (1)

60-82: ⚠️ Potential issue | 🟡 Minor

Duplicate entries in manualRelatedAssetIndex for ethAssetId — likely a merge artifact.

katanaAssetId appears at lines 65, 72, and 76 (3×), and megaethAssetId appears at lines 67, 74, and 77 (3×). These duplicates look like remnants from resolving merge conflicts across the sequential PR series. While they won't crash at runtime (the array is consumed via .includes() and Set dedup in other paths), they're incorrect data.

Proposed fix: remove duplicate entries
   [ethAssetId]: [
     optimismAssetId,
     arbitrumAssetId,
     baseAssetId,
     katanaAssetId,
     megaethAssetId,
     zkSyncEraChainId,
     blastAssetId,
     worldChainAssetId,
     hemiAssetId,
     inkAssetId,
-    katanaAssetId,
     lineaAssetId,
-    megaethAssetId,
     scrollAssetId,
-    katanaAssetId,
-    megaethAssetId,
     unichainAssetId,
     bobAssetId,
     modeAssetId,
     soneiumAssetId,
   ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts`
around lines 60 - 82, The manualRelatedAssetIndex entry for ethAssetId contains
duplicate asset ids (katanaAssetId and megaethAssetId repeated multiple times);
edit the manualRelatedAssetIndex object to remove repeated values from the
ethAssetId array so each related asset id appears only once (e.g., ensure
katanaAssetId and megaethAssetId are present a single time), preserving the
original order otherwise; update the ethAssetId array in
generateRelatedAssetIndex.ts where manualRelatedAssetIndex is defined.
packages/caip/src/constants.ts (1)

348-393: ⚠️ Potential issue | 🟠 Major

Add flowEvmAssetId (and bobAssetId, modeAssetId) to FEE_ASSET_IDS array.

The flowEvmAssetId is declared at line 30 and actively used in chainIdToFeeAssetId.ts to map KnownChainIds.FlowEvmMainnet to its native fee asset, but is missing from the FEE_ASSET_IDS array. This inconsistency should be resolved by adding it (and bobAssetId, modeAssetId which have the same issue) to the array to keep the fee asset definitions in sync.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/caip/src/constants.ts` around lines 348 - 393, The FEE_ASSET_IDS
array is missing flowEvmAssetId, bobAssetId, and modeAssetId which causes
inconsistency with mappings (e.g., chainIdToFeeAssetId.ts mapping
KnownChainIds.FlowEvmMainnet to flowEvmAssetId); update the FEE_ASSET_IDS
constant by adding flowEvmAssetId, bobAssetId, and modeAssetId into the exported
array so the declared asset IDs are listed alongside the other fee asset
constants.
🧹 Nitpick comments (6)
packages/utils/src/getChainShortName.ts (1)

63-64: 'ETH_E' is the only short name containing an underscore — consider a pure-letter alternative.

Every other entry in this switch returns an all-letter string (ETH, KAT, CELO, etc.). ETH_E is the sole exception. Beyond the visual inconsistency, downstream consumers that treat short names as opaque identifiers (URL slugs, composite keys, regex patterns) may behave unexpectedly with an embedded underscore.

An all-letter alternative like ETRL or ETHRL would stay consistent and avoid any separator ambiguity.

♻️ Suggested rename
     case KnownChainIds.EtherealMainnet:
-      return 'ETH_E'
+      return 'ETRL'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/utils/src/getChainShortName.ts` around lines 63 - 64, The short name
for KnownChainIds.EtherealMainnet in getChainShortName currently returns 'ETH_E'
with an underscore; change it to a pure-letter identifier (e.g., 'ETHRL' or
'ETRL') in the KnownChainIds.EtherealMainnet case of the getChainShortName
switch so it matches the all-letter convention used elsewhere, and update any
tests or downstream references that expect 'ETH_E' to use the new value.
packages/hdwallet-core/src/wallet.ts (1)

586-589: supportsEthereal is placed after the HDWallet interface, unlike all other supports* guards.

All other chain support type guards (lines 116–266) are grouped together before the HDWalletInfo and HDWallet interfaces. This function is appended at the very end of the file. Consider moving it to sit alongside its peers for discoverability.

Suggested placement

Move supportsEthereal to the block of EVM chain support guards (e.g., after supportsSoneium at line 266):

 export function supportsSoneium(wallet: HDWallet): wallet is ETHWallet {
   return isObject(wallet) && (wallet as any)._supportsSoneium
 }
+
+export function supportsEthereal(wallet: HDWallet): wallet is ETHWallet {
+  return isObject(wallet) && (wallet as any)._supportsEthereal
+}
 
 export function infoCosmos(info: HDWalletInfo): info is CosmosWalletInfo {

And remove the duplicate at the end of the file (lines 586–589).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/hdwallet-core/src/wallet.ts` around lines 586 - 589, The
supportsEthereal type-guard is misplaced after the HDWallet interface and
duplicated; move the supportsEthereal function into the existing block of chain
support guards (e.g., immediately after supportsSoneium in the EVM guards group)
so it sits with the other supports* functions, and delete the duplicate
definition currently appended at the end of the file; ensure the moved function
still exports the same signature (supportsEthereal(wallet: HDWallet): wallet is
ETHWallet) and retains the original implementation.
packages/swap-widget/src/components/SwapWidget.tsx (4)

612-644: ERC-20 approval doesn't check existing allowance — users may pay for unnecessary approval transactions.

The code always sends an approve transaction when quoteResponse.approval?.isRequired is truthy, without first reading the current allowance. If the user already has sufficient allowance (e.g., from a previous swap), this wastes gas on a redundant on-chain approval. A readContract call for allowance(owner, spender) before sending the approval would avoid this.

Also, the approve amount is set to exactly sellAmountBaseUnit (line 628). This means every subsequent swap of the same token to the same spender requires a new approval. Consider using maxUint256 if the UX preference is "approve once", or keep exact amounts if security-conscious — but document the intent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swap-widget/src/components/SwapWidget.tsx` around lines 612 - 644,
In SwapWidget.tsx, before sending the approve transaction inside the block that
checks quoteResponse.approval?.isRequired, first read the current ERC‑20
allowance by calling readContract/allowance(owner: walletAddress, spender:
quoteResponse.approval.spender) for the token at sellAssetAddress; only call
client.sendTransaction for approve if the current allowance is <
sellAmountBaseUnit. Also decide and document whether to approve exactly
sellAmountBaseUnit (current behavior) or use maxUint256 for a one‑time
approve—implement the chosen amount when building approvalData passed to
client.sendTransaction and keep the existing waitForTransactionReceipt flow
(createPublicClient / waitForTransactionReceipt) unchanged.

178-186: Redundant aliases: canExecuteDirectlyisSellAssetEvm, canExecuteUtxoisSellAssetUtxo, canExecuteSolanaisSellAssetSolana.

These aliases add no semantic distinction and are used interchangeably with the originals (e.g., handleExecuteSwap checks both isSellAssetUtxo and canExecuteUtxo). Collapsing to one set of names would reduce cognitive overhead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swap-widget/src/components/SwapWidget.tsx` around lines 178 - 186,
The three boolean aliases canExecuteDirectly, canExecuteUtxo, and
canExecuteSolana are redundant with isSellAssetEvm, isSellAssetUtxo, and
isSellAssetSolana; remove the canExecute* declarations and update all usages
(e.g., inside handleExecuteSwap and any conditional rendering) to reference
isSellAssetEvm / isSellAssetUtxo / isSellAssetSolana directly (ensure
imports/props unaffected), then run tests/type checks to confirm no remaining
references to canExecuteDirectly/canExecuteUtxo/canExecuteSolana.

371-374: Multiple setTimeout calls without cleanup — potential stale updates after unmount or re-execution.

executeUtxoSwap, executeSolanaSwap, and executeEvmSwap all schedule setTimeout for balance refetching without storing timer IDs or cleaning them up. If the user navigates away or triggers another swap before the timers fire, refetchSellBalance/refetchBuyBalance will execute against stale context. While React 18+ won't throw on unmounted setState, the refetches are still wasteful network calls.

Consider storing timeout IDs in a ref and clearing them on unmount via a cleanup useEffect, or using the query client's invalidateQueries with a proper polling interval.

Also applies to: 520-523, 682-698

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swap-widget/src/components/SwapWidget.tsx` around lines 371 - 374,
The three swap executor functions (executeUtxoSwap, executeSolanaSwap,
executeEvmSwap) schedule setTimeouts that call
refetchSellBalance/refetchBuyBalance without capturing or clearing timer IDs;
store each timeout ID in a React ref (e.g., balanceRefetchTimersRef) when you
call setTimeout and add a cleanup useEffect that clears all timers on unmount
(clearTimeout), or replace the timeouts with a single
queryClient.invalidateQueries or a debounced refetch to avoid redundant network
calls; update all occurrences (the setTimeout calls around
refetchSellBalance/refetchBuyBalance) to push timer IDs into the ref and ensure
the cleanup effect clears them.

135-1283: SwapWidgetCore is ~1,150 lines — consider extracting execution logic into custom hooks.

The three execute*Swap callbacks alone account for ~400 lines. Extracting them into hooks like useEvmSwapExecution, useUtxoSwapExecution, and useSolanaSwapExecution would improve readability and testability without changing behavior. The buttonText and isButtonDisabled memos are also good extraction candidates.

As per coding guidelines: "KEEP component files under 200 lines when possible; BREAK DOWN large components into smaller, reusable pieces" and "EXTRACT complex logic into custom hooks."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swap-widget/src/components/SwapWidget.tsx` around lines 135 - 1283,
The SwapWidgetCore is too large; extract the large execution and UI logic into
hooks to reduce file size and improve testability: move the executeEvmSwap,
executeSolanaSwap, and executeUtxoSwap callbacks into separate hooks (e.g.,
useEvmSwapExecution, useSolanaSwapExecution, useUtxoSwapExecution) that accept
the necessary inputs (apiClient, walletClient, walletAddress, sellAsset,
buyAsset, sellAmountBaseUnit, sellAssetBalance,
signPsbt/sendBitcoinTransfer/sendSolanaTransaction, slippage,
effectiveReceiveAddress, refetchSellBalance/refetchBuyBalance,
onSwapSuccess/onSwapError, resetBitcoinState/resetSolanaState, etc.) and return
an execute function plus any state (isExecuting, txStatus setters, reset hooks);
also extract the buttonText and isButtonDisabled logic into a small hook (e.g.,
useSwapButtonState) that consumes sell/buy asset metadata, connection states,
rates, and execution flags and returns text/disabled; replace the inline
callbacks and memos with these hooks, keep prop and behavior identical, and
ensure all dependencies are forwarded so unit tests can target the hooks
directly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/chain-adapters/src/evm/EvmBaseAdapter.ts`:
- Around line 392-407: The targetNetwork object literal has missing closing
braces for multiple entries (e.g., KnownChainIds.EtherealMainnet,
KnownChainIds.CeloMainnet, KnownChainIds.FlowEvmMainnet,
KnownChainIds.PlumeMainnet, etc.), causing a syntax error; fix by adding the
missing closing "}," after each chain entry inside the targetNetwork definition
(ensure each property object like the one for KnownChainIds.EtherealMainnet ends
with "},") so every entry is a properly terminated object before the next
KnownChainIds key.

In `@packages/chain-adapters/src/evm/index.ts`:
- Line 3: Restore the removed type guard or update consumers: either re-export
the isSecondClassEvmAdapter function from the evm index (so current import sites
keep working) or change consumers to use an instanceof check against
SecondClassEvmAdapter (replace calls like isSecondClassEvmAdapter(adapter) with
adapter instanceof SecondClassEvmAdapter and adjust imports to import
SecondClassEvmAdapter). Ensure the symbol names match exactly:
isSecondClassEvmAdapter and SecondClassEvmAdapter, and update/imports in the
consumer modules that currently call isSecondClassEvmAdapter so they compile
without breaking.

In `@packages/contracts/src/viemClient.ts`:
- Around line 185-196: Several createPublicClient declarations
(viemEtherealClient, viemCeloClient, viemFlowEvmClient, viemPlumeClient,
viemStoryClient, viemZkSyncEraClient, viemBlastClient, viemWorldChainClient,
viemHemiClient) are left unclosed and cause a TypeScript syntax error; for each
of those exported constants, close the object call and cast to the PublicClient
type by appending the missing closing sequence "}) as PublicClient" immediately
after the transport(...) configuration so each declaration matches the pattern
used by viemLineaClient.

In `@packages/swap-widget/src/components/SwapWidget.tsx`:
- Around line 359-365: The txStatus update that sets status:'pending' with
txHash in executeUtxoSwap and executeSolanaSwap is immediately overwritten by
the following status:'success' call (so the pending state is never shown);
either insert an actual await-based confirmation step between the two
setTxStatus calls (confirm the transaction via the chain-specific confirmation
method and only set success after confirmation) or remove the initial
setTxStatus({...status:'pending'...}) in both executeUtxoSwap and
executeSolanaSwap if the intent is to treat "submitted" as final; update the
code paths in those functions (executeUtxoSwap, executeSolanaSwap) accordingly
so txStatus reflects the real lifecycle.
- Around line 974-983: The onChange handler for the sell amount input allows
multiple decimal points because it only strips non-digit/dot chars; update the
handler used with setSellAmount to normalize the value so only the first decimal
point is kept (remove any subsequent dots) before calling setSellAmount, then
still call setSelectedRate(null) and setTxStatus(null); target the inline
onChange for the input that currently uses
setSellAmount(e.target.value.replace(/[^0-9.]/g, '')) and replace its
normalization logic to collapse extra dots (e.g., split on '.', keep the first
dot and join remaining parts) so downstream parsing (parseAmount/parseFloat)
never receives values like "1.2.3".
- Around line 604-610: The fallback chain created when
VIEM_CHAINS_BY_ID[requiredChainId] is missing sets rpcUrls: { default: { http:
[] } }, which will break createPublicClient/publicClient; update the logic
around viemChain/chain so that when viemChain is undefined you derive a usable
RPC URL (e.g., extract an RPC endpoint from baseAsset.metadata or
baseAsset.explorer, or use a sensible default RPC for the network) and populate
rpcUrls.default.http with that URL, and additionally guard the code that
constructs/uses the publicClient (the createPublicClient call and any
wait-for-approval flow) to skip or fail gracefully if no valid RPC is available;
references: VIEM_CHAINS_BY_ID, viemChain, chain, requiredChainId, baseAsset,
publicClient/createPublicClient.
- Around line 1194-1205: The transaction explorer URL construction in SwapWidget
(the inline href using isSellAssetUtxo/isSellAssetSolana and
sellAsset.explorerTxLink with txStatus.txHash) can produce malformed URLs when
sellAsset.explorerTxLink lacks a trailing slash; update the href logic to
normalize the base link before concatenation (e.g., ensure
sellAsset.explorerTxLink ends with a '/' or otherwise join with a '/' if
missing) so the final URL is always base + separator + txStatus.txHash, while
keeping the special-cases for mempool.space and solscan intact.
- Around line 41-55: The current VIEM_CHAINS_BY_ID map is incomplete and the
fallback chain construction creates rpcUrls: { default: { http: [] } }, which
causes createPublicClient + waitForTransactionReceipt to throw UrlRequiredError
for unsupported chains; update the code so that either (A) you add the missing
chain entries to VIEM_CHAINS_BY_ID (referencing VIEM_CHAINS_BY_ID) with valid
rpcUrls, or (B) change the fallback logic that builds the chain object to use a
configurable fallback RPC provider (read from env/config) and populate
rpcUrls.default.http with that URL before calling createPublicClient and
waitForTransactionReceipt, and if no fallback is configured, throw a clear error
instead of supplying an empty http array.

In `@packages/types/src/zerion.ts`:
- Around line 56-57: Remove the unsupported 'ethereal' entry from the
ZERION_CHAINS array in packages/types/src/zerion.ts so API calls to Zerion use
only valid chain identifiers (e.g., keep 'celo' but delete 'ethereal'); update
the ZERION_CHAINS constant (and any related exports or tests referencing
ZERION_CHAINS) to reflect the removal and run tests/typechecks to ensure no
remaining references to 'ethereal' cause errors.

---

Outside diff comments:
In `@packages/caip/src/constants.ts`:
- Around line 348-393: The FEE_ASSET_IDS array is missing flowEvmAssetId,
bobAssetId, and modeAssetId which causes inconsistency with mappings (e.g.,
chainIdToFeeAssetId.ts mapping KnownChainIds.FlowEvmMainnet to flowEvmAssetId);
update the FEE_ASSET_IDS constant by adding flowEvmAssetId, bobAssetId, and
modeAssetId into the exported array so the declared asset IDs are listed
alongside the other fee asset constants.

In `@packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts`:
- Around line 164-195: The switch cases inside relayTokenToAssetId that handle
CHAIN_REFERENCE.EtherealMainnet, CeloMainnet, FlowEvmMainnet, PlumeMainnet,
StoryMainnet, ZkSyncEraMainnet, BlastMainnet, WorldChainMainnet, and HemiMainnet
return unterminated objects and omit assetNamespace; fix each of those case
blocks in relayTokenToAssetId by closing the returned object and adding
assetNamespace: ASSET_NAMESPACE.slip44 (e.g., return { assetReference:
ASSET_REFERENCE.Ethereal, assetNamespace: ASSET_NAMESPACE.slip44 };), ensuring
each case has the proper closing brace and semicolon so TypeScript compiles.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts`:
- Around line 53-84: The manualRelatedAssetIndex defined in
generateChainRelatedAssetIndex.ts is missing many entries present in the full
generateRelatedAssetIndex (causing per-chain runs to omit manual links); update
manualRelatedAssetIndex in generateChainRelatedAssetIndex (or refactor to
import/share the single source) to include the same asset keys (e.g.,
zkSyncEraAssetId, blastAssetId, worldChainAssetId, hemiAssetId, unichainAssetId,
bobAssetId, modeAssetId, soneiumAssetId and any others present in
generateRelatedAssetIndex/generateRelatedAssetIndex.ts) so per-chain generation
via generateChainRelatedAssetIndex() matches the full generation, or
alternatively add a comment documenting the intentional split and which keys are
omitted.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts`:
- Around line 60-82: The manualRelatedAssetIndex entry for ethAssetId contains
duplicate asset ids (katanaAssetId and megaethAssetId repeated multiple times);
edit the manualRelatedAssetIndex object to remove repeated values from the
ethAssetId array so each related asset id appears only once (e.g., ensure
katanaAssetId and megaethAssetId are present a single time), preserving the
original order otherwise; update the ethAssetId array in
generateRelatedAssetIndex.ts where manualRelatedAssetIndex is defined.

---

Nitpick comments:
In `@packages/hdwallet-core/src/wallet.ts`:
- Around line 586-589: The supportsEthereal type-guard is misplaced after the
HDWallet interface and duplicated; move the supportsEthereal function into the
existing block of chain support guards (e.g., immediately after supportsSoneium
in the EVM guards group) so it sits with the other supports* functions, and
delete the duplicate definition currently appended at the end of the file;
ensure the moved function still exports the same signature
(supportsEthereal(wallet: HDWallet): wallet is ETHWallet) and retains the
original implementation.

In `@packages/swap-widget/src/components/SwapWidget.tsx`:
- Around line 612-644: In SwapWidget.tsx, before sending the approve transaction
inside the block that checks quoteResponse.approval?.isRequired, first read the
current ERC‑20 allowance by calling readContract/allowance(owner: walletAddress,
spender: quoteResponse.approval.spender) for the token at sellAssetAddress; only
call client.sendTransaction for approve if the current allowance is <
sellAmountBaseUnit. Also decide and document whether to approve exactly
sellAmountBaseUnit (current behavior) or use maxUint256 for a one‑time
approve—implement the chosen amount when building approvalData passed to
client.sendTransaction and keep the existing waitForTransactionReceipt flow
(createPublicClient / waitForTransactionReceipt) unchanged.
- Around line 178-186: The three boolean aliases canExecuteDirectly,
canExecuteUtxo, and canExecuteSolana are redundant with isSellAssetEvm,
isSellAssetUtxo, and isSellAssetSolana; remove the canExecute* declarations and
update all usages (e.g., inside handleExecuteSwap and any conditional rendering)
to reference isSellAssetEvm / isSellAssetUtxo / isSellAssetSolana directly
(ensure imports/props unaffected), then run tests/type checks to confirm no
remaining references to canExecuteDirectly/canExecuteUtxo/canExecuteSolana.
- Around line 371-374: The three swap executor functions (executeUtxoSwap,
executeSolanaSwap, executeEvmSwap) schedule setTimeouts that call
refetchSellBalance/refetchBuyBalance without capturing or clearing timer IDs;
store each timeout ID in a React ref (e.g., balanceRefetchTimersRef) when you
call setTimeout and add a cleanup useEffect that clears all timers on unmount
(clearTimeout), or replace the timeouts with a single
queryClient.invalidateQueries or a debounced refetch to avoid redundant network
calls; update all occurrences (the setTimeout calls around
refetchSellBalance/refetchBuyBalance) to push timer IDs into the ref and ensure
the cleanup effect clears them.
- Around line 135-1283: The SwapWidgetCore is too large; extract the large
execution and UI logic into hooks to reduce file size and improve testability:
move the executeEvmSwap, executeSolanaSwap, and executeUtxoSwap callbacks into
separate hooks (e.g., useEvmSwapExecution, useSolanaSwapExecution,
useUtxoSwapExecution) that accept the necessary inputs (apiClient, walletClient,
walletAddress, sellAsset, buyAsset, sellAmountBaseUnit, sellAssetBalance,
signPsbt/sendBitcoinTransfer/sendSolanaTransaction, slippage,
effectiveReceiveAddress, refetchSellBalance/refetchBuyBalance,
onSwapSuccess/onSwapError, resetBitcoinState/resetSolanaState, etc.) and return
an execute function plus any state (isExecuting, txStatus setters, reset hooks);
also extract the buttonText and isButtonDisabled logic into a small hook (e.g.,
useSwapButtonState) that consumes sell/buy asset metadata, connection states,
rates, and execution flags and returns text/disabled; replace the inline
callbacks and memos with these hooks, keep prop and behavior identical, and
ensure all dependencies are forwarded so unit tests can target the hooks
directly.

In `@packages/utils/src/getChainShortName.ts`:
- Around line 63-64: The short name for KnownChainIds.EtherealMainnet in
getChainShortName currently returns 'ETH_E' with an underscore; change it to a
pure-letter identifier (e.g., 'ETHRL' or 'ETRL') in the
KnownChainIds.EtherealMainnet case of the getChainShortName switch so it matches
the all-letter convention used elsewhere, and update any tests or downstream
references that expect 'ETH_E' to use the new value.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ed76a94 and c26858e.

⛔ Files ignored due to path filters (6)
  • public/generated/asset-manifest.json is excluded by !**/generated/**
  • public/generated/asset-manifest.json.br is excluded by !**/generated/**
  • public/generated/asset-manifest.json.gz is excluded by !**/*.gz, !**/generated/**
  • public/generated/generatedAssetData.json is excluded by !**/generated/**
  • public/generated/generatedAssetData.json.br is excluded by !**/generated/**
  • public/generated/generatedAssetData.json.gz is excluded by !**/*.gz, !**/generated/**
📒 Files selected for processing (71)
  • .beads/ss-dx5.12.json
  • .beads/ss-dx5.15.json
  • .beads/ss-dx5.17.json
  • .claude/contracts/second-class-evm-chain.md
  • .env
  • .env.development
  • headers/csps/chains/ethereal.ts
  • headers/csps/chains/flowEvm.ts
  • headers/csps/index.ts
  • packages/caip/src/adapters/coingecko/index.ts
  • packages/caip/src/constants.ts
  • packages/chain-adapters/src/evm/EvmBaseAdapter.ts
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
  • packages/chain-adapters/src/evm/ethereal/EtherealChainAdapter.ts
  • packages/chain-adapters/src/evm/ethereal/index.ts
  • packages/chain-adapters/src/evm/index.ts
  • packages/chain-adapters/src/evm/mantle/MantleChainAdapter.ts
  • packages/chain-adapters/src/types.ts
  • packages/contracts/src/ethersProviderSingleton.ts
  • packages/contracts/src/viemClient.ts
  • packages/hdwallet-coinbase/src/coinbase.ts
  • packages/hdwallet-core/src/ethereum.ts
  • packages/hdwallet-core/src/wallet.ts
  • packages/hdwallet-gridplus/src/gridplus.ts
  • packages/hdwallet-keepkey/src/keepkey.ts
  • packages/hdwallet-ledger/src/ledger.ts
  • packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts
  • packages/hdwallet-native/src/ethereum.ts
  • packages/hdwallet-phantom/src/phantom.ts
  • packages/hdwallet-trezor/src/trezor.ts
  • packages/hdwallet-vultisig/src/vultisig.ts
  • packages/hdwallet-walletconnectv2/src/walletconnectV2.ts
  • packages/swap-widget/src/components/SwapWidget.tsx
  • packages/swapper/src/swappers/AcrossSwapper/constant.ts
  • packages/swapper/src/swappers/RelaySwapper/constant.ts
  • packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
  • packages/types/src/base.ts
  • packages/types/src/zerion.ts
  • packages/utils/src/assetData/baseAssets.ts
  • packages/utils/src/assetData/getBaseAsset.ts
  • packages/utils/src/chainIdToFeeAssetId.ts
  • packages/utils/src/getAssetNamespaceFromChainId.ts
  • packages/utils/src/getChainShortName.ts
  • packages/utils/src/getNativeFeeAssetReference.ts
  • scripts/generateAssetData/ethereal/index.ts
  • scripts/generateAssetData/generateAssetData.ts
  • scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts
  • scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts
  • src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
  • src/config.ts
  • src/constants/chains.ts
  • src/context/PluginProvider/PluginProvider.tsx
  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts
  • src/lib/account/evm.ts
  • src/lib/asset-service/service/AssetService.ts
  • src/lib/coingecko/utils.ts
  • src/lib/utils/celo.ts
  • src/lib/utils/ethereal.ts
  • src/lib/utils/flowEvm.ts
  • src/lib/utils/story.ts
  • src/pages/Markets/components/MarketsRow.tsx
  • src/plugins/activePlugins.ts
  • src/plugins/ethereal/index.tsx
  • src/plugins/flowEvm/index.tsx
  • src/state/migrations/index.ts
  • src/state/slices/opportunitiesSlice/mappings.ts
  • src/state/slices/portfolioSlice/utils/index.ts
  • src/state/slices/preferencesSlice/preferencesSlice.ts
  • src/test/mocks/store.ts
  • src/vite-env.d.ts
💤 Files with no reviewable changes (4)
  • packages/chain-adapters/src/evm/mantle/MantleChainAdapter.ts
  • src/state/migrations/index.ts
  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/vite-env.d.ts

gomesalexandre and others added 5 commits February 23, 2026 18:49
- fix sonic coingecko platform: sonic-3 (native coin id) -> sonic (asset platform id)
- restore viemClient.ts to develop base + add ethereal chain/client
- restore WalletConnectV2/config.ts: re-add flowEvmChain + all new second-class chains (mantle, cronos, sonic, unichain, bob, mode, soneium, hemi, worldchain, blast, zksync, story, plume, celo)
- restore vite-env.d.ts: re-add removed chain env var declarations + ethereal
- restore migrations/index.ts: re-add clearAssets 296-304, add 305 for ethereal
- fix portfolioSlice/utils: add missing plumeChainId to accountIdToLabel
- delete dead code util files: celo.ts, ethereal.ts, flowEvm.ts, story.ts in src/lib/utils/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- restore SecondClassEvmAdapter.ts to develop base (re-adds isSecondClassEvmAdapter, getTransactionStatus, all wrapped native contracts for blast/zksyncEra/hemi/worldChain/celo/flowEvm/story)
- add plumeChainId to WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID (0xea237441...)
- restore isSecondClassEvmAdapter export in chain-adapters evm/index.ts
- add EtherealMainnet to ETHSignTx signing map in types.ts
- fix PlumeMainnet missing from coingecko chainIdToCoingeckoAssetPlatform switch
- update generated asset data (plume: 54 assets, celo: 39 assets w/ WCELO, ethereal: precision 18 fixed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… ethereal removal

- add missing closing },  for 9 entries in targetNetwork object (EtherealMainnet through HemiMainnet)
- remove 'ethereal' from ZERION_CHAINS and zerionChainIdToChainId map (zerion doesn't support ethereal)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
adds cronos, unichain, sonic, zksync, worldchain, flowMainnet, story, soneium, mantle, celo, hemi, ink, linea, bob, blast, plumeMainnet, scroll - prevents UrlRequiredError during approval tx polling for these chains

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merge artifact - EtherealMainnet through HemiMainnet cases were all
missing assetNamespace and closing } in the slip44 return objects.

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

@coderabbitai gm mr robot did you capture an issue for cross-chain Relay swaps to CELO missing second-class Tx history/execution price>

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for GitHub issues related to CELO, Relay swaps, transaction history, and execution price
gh issue list --repo shapeshift/web --search "CELO Relay" --limit 20 --json number,title,body,state,createdAt,author

echo "---"

# Also search for issues about second-class chains and transaction history
gh issue list --repo shapeshift/web --search "second-class transaction history" --limit 20 --json number,title,body,state,createdAt,author

echo "---"

# Search for execution price issues
gh issue list --repo shapeshift/web --search "execution price CELO" --limit 20 --json number,title,body,state,createdAt,author

echo "---"

# Search for Relay swapper issues
gh issue list --repo shapeshift/web --search "Relay swap history" --limit 20 --json number,title,body,state,createdAt,author

Length of output: 23


🏁 Script executed:

#!/bin/bash
# Search more broadly for CELO-related issues
gh issue list --repo shapeshift/web --search "CELO" --limit 30 --json number,title,body,state,createdAt,author

echo "---"

# Search for issues created by coderabbitai or related bots
gh issue list --repo shapeshift/web --author coderabbitai --limit 50 --json number,title,body,state,createdAt

echo "---"

# Search for any second-class chain related issues
gh issue list --repo shapeshift/web --search "second-class" --limit 30 --json number,title,body,state,createdAt,author

echo "---"

# Search for transaction history issues more broadly
gh issue list --repo shapeshift/web --search "transaction history" --limit 30 --json number,title,body,state,createdAt,author

Length of output: 69759


@gomesalexandre gm! 👋

No, I did not find or capture an existing issue for cross-chain Relay swaps to CELO missing second-class transaction history/execution price. My search across the repository returned no issues matching that specific problem (CELO + Relay swaps + tx history/execution price).

I did find issue #11486 which tracks a similar problem for Cetus swaps on SUI (missing execution price), but nothing specific to CELO + Relay.

Would you like me to create a new issue to track this as a follow-up for the second-class chain integration work? If so, I can open it with the relevant context about CELO being a second-class Relay chain and the missing transaction history/execution price data.


🧠 Learnings used
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:91-95
Timestamp: 2025-09-12T13:43:50.695Z
Learning: gomesalexandre dismissed gas calculation overflow validation in useSimulateEvmTransaction hook as "stale", preferring to trust Tenderly's simulation data without defensive validation checks, consistent with his established pattern of relying on external service quality over defensive programming in WalletConnect flows.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

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: 10566
File: src/hooks/useLedgerConnectionState.ts:1-1
Timestamp: 2025-09-24T20:44:29.333Z
Learning: gomesalexandre prefers not to touch complex connection state logic in useLedgerConnectionState when the current implementation is working, even when potential stale closure issues are identified, demonstrating his cautious approach to modifying intricate state management code within PR scope.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:27-31
Timestamp: 2025-09-11T22:53:19.837Z
Learning: gomesalexandre trusts Tenderly's data quality and doesn't want defensive validation for gas values (transaction?.gasLimit ?? transaction?.gas) in WalletConnect flows, preferring to rely on the external service providing valid hex values.

Learnt from: gomes-bot
Repo: shapeshift/web PR: 12024
File: src/pages/ChainflipLending/Pool/components/Deposit/DepositConfirm.tsx:220-225
Timestamp: 2026-02-24T17:33:04.476Z
Learning: In Chainflip Lending PoC (src/pages/ChainflipLending), gomesalexandre prefers to keep raw error messages from the deposit machine context displayed directly in the UI for debugging purposes, deferring user-friendly error message mapping to a future improvement rather than implementing it during initial development.

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: 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.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:0-0
Timestamp: 2025-09-12T09:58:57.389Z
Learning: gomesalexandre prefers letting errors throw and propagate up the call stack in form submit handlers rather than adding local try/catch error handling, consistent with his fail-fast approach in WalletConnect transaction confirmation 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.

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: 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.

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.

@gomesalexandre
Copy link
Contributor

Would you like me to create a new issue to track this as a follow-up for the second-class chain integration work? If so, I can open it with the relevant context about CELO being a second-class Relay chain and the missing transaction history/execution price data.

@coderabbitai do it

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create GitHub issue for CELO Relay swap transaction history/execution price tracking

gh issue create \
  --repo shapeshift/web \
  --title "Cross-chain Relay swaps to CELO missing transaction history and execution price" \
  --assignee gomesalexandre \
  --body "## Problem

Cross-chain Relay swaps to CELO (a second-class chain) are missing:
- Transaction history display
- Execution price data

This affects users swapping to CELO via the Relay protocol, as they cannot see their swap history or the actual execution price they received.

## Context

CELO was integrated as a second-class Relay chain in the recent chain integration work. While the swap functionality itself works, the transaction history and execution price tracking for these swaps are not yet implemented.

This is a follow-up item identified during review of the Ethereal integration PR.

## Expected Behavior

- Users should see Relay swap transactions to CELO in their transaction history
- Execution prices should be displayed for completed CELO swaps

## Related

- PR: https://github.com/shapeshift/web/pull/11940
- Comment: https://github.com/shapeshift/web/pull/11940#discussion_r1908390000
- Reported by: `@gomesalexandre`
- Similar issue for Cetus/SUI: `#11486`"

Length of output: 46


@gomesalexandre Done! ✅

I've created issue #12033 to track the missing transaction history and execution price for cross-chain Relay swaps to CELO.

The issue includes:

  • Clear description of what's missing (tx history display + execution price data)
  • Context about CELO being a second-class Relay chain
  • Backlinks to this PR and comment thread
  • Reference to the similar issue for Cetus/SUI (#11486)
  • Assigned to you

🧠 Learnings used
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: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/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: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:91-95
Timestamp: 2025-09-12T13:43:50.695Z
Learning: gomesalexandre dismissed gas calculation overflow validation in useSimulateEvmTransaction hook as "stale", preferring to trust Tenderly's simulation data without defensive validation checks, consistent with his established pattern of relying on external service quality over defensive programming in WalletConnect flows.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

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

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/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: 11261
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx:117-172
Timestamp: 2025-12-03T23:16:28.342Z
Learning: In TRON transaction confirmation polling (e.g., approval flows in useAllowanceApproval.tsx), gomesalexandre is comfortable with optimistic completion when polling times out after the configured duration (e.g., 60 seconds). He considers the timeout a "paranoia" safety net for unlikely scenarios, expecting normal transactions to complete much faster. He prefers to defer more sophisticated timeout/failure handling as a separate follow-up concern rather than expanding PR scope.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:27-31
Timestamp: 2025-09-11T22:53:19.837Z
Learning: gomesalexandre trusts Tenderly's data quality and doesn't want defensive validation for gas values (transaction?.gasLimit ?? transaction?.gas) in WalletConnect flows, preferring to rely on the external service providing valid hex values.

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.

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.

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.

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: 4

Caution

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

⚠️ Outside diff range comments (2)
packages/caip/src/constants.ts (2)

299-316: ⚠️ Potential issue | 🔴 Critical

Bug: CHAIN_REFERENCE.CeloMainnet is duplicated in VALID_CHAIN_IDS.

CeloMainnet appears at both line 300 and line 316 in the EVM chain references array. Remove the duplicate entry at line 316.

🐛 Proposed fix
     CHAIN_REFERENCE.SoneiumMainnet,
     CHAIN_REFERENCE.SeiMainnet,
-    CHAIN_REFERENCE.CeloMainnet,
   ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/caip/src/constants.ts` around lines 299 - 316, The VALID_CHAIN_IDS
(EVM chain references array) contains a duplicate entry
CHAIN_REFERENCE.CeloMainnet; remove the second occurrence (the later
CHAIN_REFERENCE.CeloMainnet in the array) so each CHAIN_REFERENCE value appears
only once, leaving the first CeloMainnet entry intact in the CHAIN_REFERENCE
list in packages/caip/src/constants.ts.

354-400: ⚠️ Potential issue | 🔴 Critical

Add flowEvmAssetId to FEE_ASSET_IDS array.

flowEvmAssetId was removed from FEE_ASSET_IDS during reordering. It was previously included when Flow EVM was integrated in commit 6999bfa but is missing from the current array, causing fee estimation failures for Flow EVM transactions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/caip/src/constants.ts` around lines 354 - 400, FEE_ASSET_IDS is
missing flowEvmAssetId which breaks Flow EVM fee estimation; update the
FEE_ASSET_IDS array to include flowEvmAssetId (add the symbol flowEvmAssetId
into the exported array alongside the other asset ids) so Flow EVM is recognized
for fee calculations—locate the FEE_ASSET_IDS constant and insert flowEvmAssetId
in the list in a logical grouping with other EVM assets.
🧹 Nitpick comments (3)
scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts (1)

72-77: Remove duplicated katanaAssetId/megaethAssetId entries in the ETH related-assets list.

Line 72/74/76/77 re-add values already listed at Line 65/66. Even though later logic dedupes, this manual index should stay canonical and unambiguous.

Suggested cleanup
   [ethAssetId]: [
     optimismAssetId,
     arbitrumAssetId,
     baseAssetId,
     katanaAssetId,
     megaethAssetId,
     zkSyncEraAssetId,
     blastAssetId,
     worldChainAssetId,
     hemiAssetId,
     inkAssetId,
-    katanaAssetId,
     lineaAssetId,
-    megaethAssetId,
     scrollAssetId,
-    katanaAssetId,
-    megaethAssetId,
     unichainAssetId,
     bobAssetId,
     modeAssetId,
     soneiumAssetId,
   ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts`
around lines 72 - 77, The ETH related-assets array in
generateRelatedAssetIndex.ts contains duplicate entries for katanaAssetId and
megaethAssetId (they appear twice); remove the repeated occurrences so each of
katanaAssetId and megaethAssetId appears only once in the literal list (leave
the existing single entries at their original positions), ensuring the manual
index is canonical even though later dedup logic exists.
packages/hdwallet-core/src/wallet.ts (1)

591-593: Minor: supportsEthereal is placed after the HDWallet interface, unlike all other chain type guards.

All other EVM chain guards (supportsFlowEvm, supportsCelo, supportsBerachain, etc.) are declared in the 116–415 range, before the HDWalletInfo and HDWallet interface definitions. Consider moving supportsEthereal into that block alongside supportsKatana and the other recently added chain guards for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/hdwallet-core/src/wallet.ts` around lines 591 - 593, Move the
supportsEthereal type-guard function so it sits with the other EVM chain guards
(e.g., alongside supportsKatana) before the HDWalletInfo/HDWallet interface
declarations; locate the existing supportsEthereal export (function
supportsEthereal(wallet: HDWallet): wallet is ETHWallet) and cut/paste it into
the EVM guards block (the area containing supportsFlowEvm, supportsCelo,
supportsBerachain, supportsKatana) to maintain consistent ordering and grouping
of chain-specific type guards.
packages/chain-adapters/src/types.ts (1)

250-250: Nit: EtherealMainnet ordering inconsistent in ChainSignTx vs other type maps.

In ChainSpecificAccount, ChainSpecificFeeData, ChainSpecificBuildTxData, and ChainSpecificGetFeeDataInput, EtherealMainnet is placed after KatanaMainnet (consistent with the rest of the PR). But in ChainSignTx, it's placed between SoneiumMainnet and SeiMainnet (line 250). Not a functional issue since TypeScript type key ordering is irrelevant, but inconsistent placement makes future maintenance harder.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/chain-adapters/src/types.ts` at line 250, Reorder the
KnownChainIds.EtherealMainnet entry in the ChainSignTx type so it appears in the
same position as in the other maps (after KatanaMainnet) to keep ordering
consistent; update the mapping in the ChainSignTx type (where
KnownChainIds.EtherealMainnet currently sits between SoneiumMainnet and
SeiMainnet) to be placed after KatanaMainnet.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env:
- Line 165: Update the VITE_ETHEREAL_NODE_URL value in the base .env to the
browser-compatible RPC endpoint used in development; replace the current
VITE_ETHEREAL_NODE_URL=https://rpc.ethereal.global with
VITE_ETHEREAL_NODE_URL=https://rpc.ethereal.trade so production builds inherit
the correct .trade endpoint (the same value present in .env.development).

In `@packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts`:
- Around line 552-572: The fallback that treats ERC20 Transfer logs as native
receives in SecondClassEvmAdapter.ts must be limited to chains where the native
token is also an ERC20 (e.g., Celo); update the block that parses Transfer logs
(using parseEventLogs, erc20Abi, wrappedNativeContract, pubkey and pushing to
internalTxs) to run only when the adapter's chainId equals celoChainId (or other
explicitly dual-native chain ids added to the same guard), so non-Celo chains
(where wrapped native tokens like WETH are pure ERC20) do not produce mistaken
native internalTxs and duplicate tokenTransfers.

In `@src/config.ts`:
- Line 73: The env var was renamed in config to VITE_FLOW_EVM_NODE_URL but the
viem client still reads process.env.VITE_FLOWEVM_NODE_URL (old key), causing the
client to ignore the provided value; update the viem client to read the new key
name (VITE_FLOW_EVM_NODE_URL) wherever process.env.VITE_FLOWEVM_NODE_URL is
referenced (e.g., in the viem client initialization logic around the Flow EVM
endpoint), and ensure any fallback logic uses the validated config value from
the renamed variable rather than the old env key.

In `@src/context/WalletProvider/WalletConnectV2/config.ts`:
- Around line 9-30: Import and include the Ethereal chain (chain id 5064014) in
the WalletConnect V2 wiring: add the Ethereal symbol to the viem/chains import
list, append it to walletConnectV2OptionalChains, include its environment
variable extraction in getConfig() alongside other optional chains, and add an
entry for Ethereal in rpcMap so WalletConnect can advertise and switch to the
Ethereal RPC; update any related arrays/objects where other second-class chains
are handled (the same places as entries for sei, soneium, sonic, story, etc.) to
mirror their handling for Ethereal.

---

Outside diff comments:
In `@packages/caip/src/constants.ts`:
- Around line 299-316: The VALID_CHAIN_IDS (EVM chain references array) contains
a duplicate entry CHAIN_REFERENCE.CeloMainnet; remove the second occurrence (the
later CHAIN_REFERENCE.CeloMainnet in the array) so each CHAIN_REFERENCE value
appears only once, leaving the first CeloMainnet entry intact in the
CHAIN_REFERENCE list in packages/caip/src/constants.ts.
- Around line 354-400: FEE_ASSET_IDS is missing flowEvmAssetId which breaks Flow
EVM fee estimation; update the FEE_ASSET_IDS array to include flowEvmAssetId
(add the symbol flowEvmAssetId into the exported array alongside the other asset
ids) so Flow EVM is recognized for fee calculations—locate the FEE_ASSET_IDS
constant and insert flowEvmAssetId in the list in a logical grouping with other
EVM assets.

---

Nitpick comments:
In `@packages/chain-adapters/src/types.ts`:
- Line 250: Reorder the KnownChainIds.EtherealMainnet entry in the ChainSignTx
type so it appears in the same position as in the other maps (after
KatanaMainnet) to keep ordering consistent; update the mapping in the
ChainSignTx type (where KnownChainIds.EtherealMainnet currently sits between
SoneiumMainnet and SeiMainnet) to be placed after KatanaMainnet.

In `@packages/hdwallet-core/src/wallet.ts`:
- Around line 591-593: Move the supportsEthereal type-guard function so it sits
with the other EVM chain guards (e.g., alongside supportsKatana) before the
HDWalletInfo/HDWallet interface declarations; locate the existing
supportsEthereal export (function supportsEthereal(wallet: HDWallet): wallet is
ETHWallet) and cut/paste it into the EVM guards block (the area containing
supportsFlowEvm, supportsCelo, supportsBerachain, supportsKatana) to maintain
consistent ordering and grouping of chain-specific type guards.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts`:
- Around line 72-77: The ETH related-assets array in
generateRelatedAssetIndex.ts contains duplicate entries for katanaAssetId and
megaethAssetId (they appear twice); remove the repeated occurrences so each of
katanaAssetId and megaethAssetId appears only once in the literal list (leave
the existing single entries at their original positions), ensuring the manual
index is canonical even though later dedup logic exists.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between afa2991 and c7e4f65.

⛔ Files ignored due to path filters (6)
  • public/generated/asset-manifest.json is excluded by !**/generated/**
  • public/generated/asset-manifest.json.br is excluded by !**/generated/**
  • public/generated/asset-manifest.json.gz is excluded by !**/*.gz, !**/generated/**
  • public/generated/generatedAssetData.json is excluded by !**/generated/**
  • public/generated/generatedAssetData.json.br is excluded by !**/generated/**
  • public/generated/generatedAssetData.json.gz is excluded by !**/*.gz, !**/generated/**
📒 Files selected for processing (52)
  • .env
  • .env.development
  • headers/csps/index.ts
  • packages/caip/src/adapters/coingecko/index.ts
  • packages/caip/src/constants.ts
  • packages/chain-adapters/src/evm/EvmBaseAdapter.ts
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
  • packages/chain-adapters/src/evm/index.ts
  • packages/chain-adapters/src/types.ts
  • packages/contracts/src/ethersProviderSingleton.ts
  • packages/contracts/src/viemClient.ts
  • packages/hdwallet-coinbase/src/coinbase.ts
  • packages/hdwallet-core/src/ethereum.ts
  • packages/hdwallet-core/src/wallet.ts
  • packages/hdwallet-gridplus/src/gridplus.ts
  • packages/hdwallet-keepkey/src/keepkey.ts
  • packages/hdwallet-ledger/src/ledger.ts
  • packages/hdwallet-metamask-multichain/src/shapeshift-multichain.ts
  • packages/hdwallet-native/src/ethereum.ts
  • packages/hdwallet-phantom/src/phantom.ts
  • packages/hdwallet-trezor/src/trezor.ts
  • packages/hdwallet-vultisig/src/vultisig.ts
  • packages/hdwallet-walletconnectv2/src/walletconnectV2.ts
  • packages/swapper/src/swappers/RelaySwapper/constant.ts
  • packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
  • packages/types/src/base.ts
  • packages/types/src/zerion.ts
  • packages/utils/src/assetData/baseAssets.ts
  • packages/utils/src/assetData/getBaseAsset.ts
  • packages/utils/src/chainIdToFeeAssetId.ts
  • packages/utils/src/getAssetNamespaceFromChainId.ts
  • packages/utils/src/getChainShortName.ts
  • packages/utils/src/getNativeFeeAssetReference.ts
  • scripts/generateAssetData/generateAssetData.ts
  • scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts
  • scripts/generateAssetData/generateRelatedAssetIndex/generateRelatedAssetIndex.ts
  • src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
  • src/config.ts
  • src/constants/chains.ts
  • src/context/PluginProvider/PluginProvider.tsx
  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts
  • src/lib/account/evm.ts
  • src/lib/asset-service/service/AssetService.ts
  • src/lib/coingecko/utils.ts
  • src/pages/Markets/components/MarketsRow.tsx
  • src/plugins/activePlugins.ts
  • src/state/slices/opportunitiesSlice/mappings.ts
  • src/state/slices/portfolioSlice/utils/index.ts
  • src/state/slices/preferencesSlice/preferencesSlice.ts
  • src/test/mocks/store.ts
  • src/vite-env.d.ts
💤 Files with no reviewable changes (1)
  • scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/context/PluginProvider/PluginProvider.tsx
  • packages/utils/src/getAssetNamespaceFromChainId.ts
  • packages/contracts/src/ethersProviderSingleton.ts
  • src/state/slices/opportunitiesSlice/mappings.ts
  • src/constants/chains.ts
  • src/lib/account/evm.ts
  • packages/hdwallet-trezor/src/trezor.ts
  • packages/hdwallet-vultisig/src/vultisig.ts
  • packages/hdwallet-gridplus/src/gridplus.ts

… rename

- export `ethereal` chain from viemClient, add to walletConnectV2OptionalChains + rpcMap
- scope direct ERC20 receive fallback in SecondClassEvmAdapter to celoChainId only
- align VITE_FLOW_EVM_NODE_URL rename: viemClient, WalletConnectV2/config, vite-env.d.ts
- fix .env base VITE_ETHEREAL_NODE_URL to use rpc.ethereal.trade (browser-compat endpoint)

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

done @coderabbitai, f9beb59

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the commit to see what was done
git log -1 --pretty=format:"Commit: %H%nAuthor: %an%nDate: %ad%nMessage: %s%n%b" f9beb5957e

echo -e "\n---\n"

# Show the files changed in this commit
git show --stat f9beb5957e

echo -e "\n---\n"

# Show the actual diff for this commit
git show f9beb5957e

Length of output: 6762


@gomesalexandre Perfect! 👍

I can see you've pushed fixes addressing several review items in f9beb595:

  1. Ethereal WalletConnect wiring — exported ethereal chain from viemClient and added it to WalletConnectV2 optional chains + RPC map
  2. CELO ERC20 guard — scoped the direct ERC20 receive fallback to celoChainId only (not all second-class chains)
  3. FlowEVM env var rename — aligned VITE_FLOW_EVM_NODE_URL across viemClient, WC config, and vite-env.d.ts
  4. Ethereal RPC URL — switched to rpc.ethereal.trade (browser-compatible endpoint)

Issue #12033 remains open for the separate follow-up work on CELO Relay swap transaction history and execution price tracking.


🧠 Learnings used
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/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: 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: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:91-95
Timestamp: 2025-09-12T13:43:50.695Z
Learning: gomesalexandre dismissed gas calculation overflow validation in useSimulateEvmTransaction hook as "stale", preferring to trust Tenderly's simulation data without defensive validation checks, consistent with his established pattern of relying on external service quality over defensive programming in WalletConnect flows.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx:117-172
Timestamp: 2025-12-03T23:16:28.342Z
Learning: In TRON transaction confirmation polling (e.g., approval flows in useAllowanceApproval.tsx), gomesalexandre is comfortable with optimistic completion when polling times out after the configured duration (e.g., 60 seconds). He considers the timeout a "paranoia" safety net for unlikely scenarios, expecting normal transactions to complete much faster. He prefers to defer more sophisticated timeout/failure handling as a separate follow-up concern rather than expanding 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: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

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

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

Learnt from: 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: 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.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11536
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeExecution.tsx:252-265
Timestamp: 2025-12-27T16:02:59.817Z
Learning: When fixing critical bugs in shapeshift/web, gomesalexandre prefers to keep changes minimal and focused on correctness rather than combining bug fixes with code quality improvements like extracting duplicated logic, even when duplication is present.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:24-30
Timestamp: 2025-08-07T12:10:58.022Z
Learning: In src/lib/moralis.ts, gomesalexandre doesn't require explicit return type annotations for simple utility functions like startMoralis, preferring to keep them concise when the return type is obvious from context.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:0-0
Timestamp: 2025-09-12T09:58:57.389Z
Learning: gomesalexandre prefers letting errors throw and propagate up the call stack in form submit handlers rather than adding local try/catch error handling, consistent with his fail-fast approach in WalletConnect transaction confirmation 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: 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.

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/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.

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.

🧹 Nitpick comments (1)
.env (1)

167-167: VITE_FLOW_EVM_NODE_URL matches the hardcoded fallback — no transport redundancy.

viemFlowEvmClient (line 191 in viemClient.ts) declares:

[process.env.VITE_FLOW_EVM_NODE_URL, 'https://mainnet.evm.nodes.onflow.org']

Since both resolve to the same URL, the fallback transport degrades to a single endpoint with no actual resilience benefit. Consider using a distinct secondary public RPC (e.g. https://flowmainnet.gateway.tenderly.co or an Ankr endpoint) as the hardcoded fallback, or dropping the duplicate entry.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.env at line 167, The environment variable VITE_FLOW_EVM_NODE_URL equals the
hardcoded fallback URL, so the viemFlowEvmClient fallback transport (where
[process.env.VITE_FLOW_EVM_NODE_URL, 'https://mainnet.evm.nodes.onflow.org'] is
used) provides no redundancy; fix by updating either the env value or the
fallback literal to a distinct public RPC endpoint (e.g.,
'https://flowmainnet.gateway.tenderly.co' or another provider) or remove the
duplicate fallback entry so viemFlowEvmClient actually has multiple unique
endpoints for resilience.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.env:
- Line 167: The environment variable VITE_FLOW_EVM_NODE_URL equals the hardcoded
fallback URL, so the viemFlowEvmClient fallback transport (where
[process.env.VITE_FLOW_EVM_NODE_URL, 'https://mainnet.evm.nodes.onflow.org'] is
used) provides no redundancy; fix by updating either the env value or the
fallback literal to a distinct public RPC endpoint (e.g.,
'https://flowmainnet.gateway.tenderly.co' or another provider) or remove the
duplicate fallback entry so viemFlowEvmClient actually has multiple unique
endpoints for resilience.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c7e4f65 and f9beb59.

📒 Files selected for processing (5)
  • .env
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
  • packages/contracts/src/viemClient.ts
  • src/context/WalletProvider/WalletConnectV2/config.ts
  • src/vite-env.d.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/context/WalletProvider/WalletConnectV2/config.ts
  • packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts

gomesalexandre and others added 3 commits February 25, 2026 16:58
- restore flowEvmAssetId to FEE_ASSET_IDS in constants.ts
- restore blastAssetId, bobAssetId, cronosAssetId, hemiAssetId, modeAssetId,
  soneiumAssetId, sonicAssetId, unichainAssetId, worldChainAssetId, zkSyncEraAssetId
  imports and manualRelatedAssetIndex entries in generateChainRelatedAssetIndex
- restore sonicAssetId, cronosAssetId imports and manualRelatedAssetIndex entries
  in generateRelatedAssetIndex; remove triplicate katanaAssetId/megaethAssetId entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
No await expression used - sync is correct here.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nshots

- yarn generate:chain story: Story IP native asset was missing (0 entries for eip155:1514)
- yarn generate:chain plume: Plume PLUME native was missing (0 entries for eip155:98866), now 54 assets
- yarn generate:chain celo: Celo had no ERC20s (0 entries for eip155:42220), now 39 assets
- add e2e/screenshots/evm_chains_batch/ with one screenshot per chain (16 chains)

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

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

agent-browser retested all (without retesting Tx execution) and confirmed happy, see screenshots:

All 16 second-class EVM chains verified in Trade page asset selector - chain icon, native asset, and popular tokens all loading correctly.

3 gaps found and fixed:

  • Story: IP native asset was missing - yarn generate:chain story (0 entries for eip155:1514)
  • Plume: PLUME native missing - yarn generate:chain plume (0 entries for eip155:98866, now 54 assets)
  • Celo: only native CELO, no ERC20s - yarn generate:chain celo (0 entries for eip155:42220, now 39 assets)

Ethereal USDe-as-native confirmed correct by design (Ethena-based chain, ethereal/index.ts intentionally returns native only).

Screenshots (one per chain):

Chain Screenshot
Mantle Mantle
Cronos Cronos
Sonic Sonic
Unichain Unichain
BOB BOB
Mode Mode
Soneium Soneium
Hemi Hemi
World Chain World Chain
Blast Blast
zkSync Era zkSync Era
Story Story
Plume Plume
Flow EVM Flow EVM
Celo Celo
Ethereal Ethereal

gomesalexandre and others added 2 commits February 25, 2026 18:12
… term)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…earch term)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre enabled auto-merge (squash) February 25, 2026 17:21
…this PR)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
gomesalexandre and others added 3 commits February 25, 2026 18:35
- reset coingecko/index.ts to origin/develop (pure ordering artifact, no ethereal)
- reset flowEvm/index.tsx, coingecko/utils.ts to origin/develop (FLOWEVM rename out of scope)
- reset vite-env.d.ts, config.ts to origin/develop then add VITE_ETHEREAL_NODE_URL + VITE_FEATURE_ETHEREAL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre enabled auto-merge (squash) February 25, 2026 17:59
gomesalexandre and others added 2 commits February 25, 2026 19:17
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- rename VITE_FLOW_EVM_NODE_URL → VITE_FLOWEVM_NODE_URL across .env, .env.development, and headers/csps/chains/flowEvm.ts
- rename VITE_FEATURE_FLOW_EVM → VITE_FEATURE_FLOWEVM to match what src/config.ts expects
- VITE_FLOWEVM_NODE_URL was missing (no default in config.ts), causing config validation to silently fail and preventing VITE_FEATURE_ETHEREAL from loading

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre merged commit 11d497c into develop Feb 25, 2026
6 checks passed
@gomesalexandre gomesalexandre deleted the feat/integrate-ethereal-relay branch February 25, 2026 20:26
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.

2 participants