Skip to content

feat: integrate Unichain (eip155:130) as second-class citizen via Relay#11924

Merged
gomesalexandre merged 47 commits intodevelopfrom
feat/integrate-unichain-relay-v2
Feb 21, 2026
Merged

feat: integrate Unichain (eip155:130) as second-class citizen via Relay#11924
gomesalexandre merged 47 commits intodevelopfrom
feat/integrate-unichain-relay-v2

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Feb 17, 2026

Description

Integrates Unichain (eip155:130) as a second-class citizen chain via Relay protocol. Unichain is an EVM L2 with ETH as native token.

This is PR 4 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) ← this PR
  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)

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

Chain details:

  • Chain ID: eip155:130
  • Native token: ETH (precision 18, ETH-native)
  • CoinGecko platform: unichain
  • Explorer: https://uniscan.xyz
  • Across swapper: supported
  • Zerion: supported

Changes across 62 files:

  • CAIP constants, types, and chain adapter
  • HDWallet support flags (all wallet implementations)
  • Relay and Across swapper mappings
  • CoinGecko adapter with unichain platform
  • Zerion chain mapping
  • Feature flag (VITE_FEATURE_UNICHAIN), plugin, CSP headers
  • Portfolio, account, asset service, and market integrations
  • Asset generation scripts and related asset index (ETH-native)
  • Test updates for ETH-native coingecko mappings

Issue (if applicable)

Part of #11902

Risk

Low risk — behind feature flag (VITE_FEATURE_UNICHAIN, default false). No existing functionality affected. Follows established second-class citizen chain integration pattern (same as Katana, MegaETH, etc.).

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

Unichain chain only, gated behind feature flag. Relay and Across swapper integrations for Unichain.

Testing

Engineering

  1. Enable Unichain feature flag via /flags route or set VITE_FEATURE_UNICHAIN=true
  2. Verify Unichain appears in chain selectors and markets
  3. Verify ETH on Unichain shows as related asset to ETH mainnet
  4. Type-check passes: yarn type-check
  5. Lint passes: yarn lint

Operations

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

Summary by CodeRabbit

  • New Features

    • Added Unichain support: wallet integrations, chain plugin, asset discovery, pricing, swaps, and popular-asset listing.
    • Transaction status tracking and RPC client support for Unichain.
  • Chores

    • Added Unichain feature flag and node URL configuration for gradual rollout.
    • Removed debug logging from swap and account flows.

…Relay bridge support

Add support for Mantle (MNT native gas) including CAIP constants, chain adapter,
plugin, feature flag, Relay swapper mapping, HDWallet support flags, CSP headers,
asset generation script, and all required shared-file entries.

Part of #11902
…lay bridge support

Add support for Cronos (CRO native gas) including CAIP constants, chain adapter,
plugin, feature flag, Relay swapper mapping, HDWallet support flags, CSP headers,
asset generation script, and all required shared-file entries.

Part of #11902
Add src/lib/utils/mantle.ts with getMantleTransactionStatus using
eth_getTransactionReceipt via the Mantle RPC.

Add KnownChainIds.MantleMainnet case to useSendActionSubscriber.tsx
so Mantle transactions resolve in the action center.
Add src/lib/utils/cronos.ts with getCronosTransactionStatus using
eth_getTransactionReceipt via the Cronos RPC.

Add KnownChainIds.CronosMainnet case to useSendActionSubscriber.tsx
so Cronos transactions resolve in the action center.

Add CHAIN_REFERENCE.CronosMainnet case to relayTokenToAssetId.ts
to prevent runtime crash on Relay swaps involving Cronos.
Address PR review feedback:
- Add mantleChainId to getCoingeckoSupportedChainIds (feature-flagged)
- Add mantle to ZERION_CHAINS array and ZERION_CHAINS_MAP
- Across does not support Mantle, skipped
Address PR review feedback:
- Add cronosChainId to getCoingeckoSupportedChainIds (feature-flagged)
- Add cronos to ZERION_CHAINS array and ZERION_CHAINS_MAP
- Across does not support Cronos, skipped
Adds full Unichain support including:
- CAIP constants, types, and chain adapter
- HDWallet support flags across all wallet implementations
- Relay and Across swapper mappings
- CoinGecko adapter with unichain platform
- Zerion chain mapping
- Feature flag, plugin, CSP headers
- Portfolio, account, asset service, and market integrations
- Asset generation scripts and related asset index (ETH-native)

Part of #11902
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

Warning

Rate limit exceeded

@gomesalexandre has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Adds Unichain (EVM chainId eip155:130) across the codebase: new chain constants, chain adapter, viem/ethers clients, HDWallet capability flags and guards, asset-generation and Coingecko mappings, swapper/relay mappings, feature flags, plugin registration, CSP, RPC env vars, UI gating, and transaction-status utilities.

Changes

Cohort / File(s) Summary
CAIP Constants & Chain IDs
packages/caip/src/constants.ts, packages/types/src/base.ts
Introduce unichainChainId/unichainAssetId, add UnichainMainnet to CHAIN_REFERENCE and EvmChainId union.
Chain Adapters & EVM infra
packages/chain-adapters/src/evm/EvmBaseAdapter.ts, packages/chain-adapters/src/evm/unichain/*, packages/chain-adapters/src/evm/index.ts, packages/chain-adapters/src/types.ts, packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
Add UnichainChainAdapter, export it, include KnownChainIds.UnichainMainnet in supported lists, add wrapped-native mapping and type mappings.
Viem / Ethers Clients & RPC
packages/contracts/src/viemClient.ts, packages/contracts/src/ethersProviderSingleton.ts
Create viemUnichainClient, wire it into client/network maps, and resolve RPC URL via VITE_UNICHAIN_NODE_URL.
HDWallet Capability Flags & Guards
packages/hdwallet-core/src/*, packages/hdwallet-*/src/*.ts (multiple)
Add _supportsUnichain flags across wallet implementations and an supportsUnichain type guard.
Coingecko Adapter & Asset Parsing
packages/caip/src/adapters/coingecko/index.ts, .../utils.ts, tests
Add Coingecko platform Unichain, mappings for chainId ↔ platform, and token parsing for Unichain; update tests.
Asset Data & Generation
packages/utils/src/assetData/baseAssets.ts, .../getBaseAsset.ts, scripts/generateAssetData/unichain/*, scripts/generateAssetData/*
Add unichainChain base asset, generator helper for Unichain assets, and include Unichain in generation/related-asset index.
Swapper / Relay Integration
packages/swapper/src/swappers/.../constant.ts, packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
Map Unichain chainId to Across/Relay chain ids and support native asset mapping for Unichain.
Env, Config & CSP
.env, .env.development, src/config.ts, src/vite-env.d.ts, headers/csps/chains/unichain.ts, headers/csps/index.ts
Add VITE_UNICHAIN_NODE_URL and VITE_FEATURE_UNICHAIN env vars/validators, type declarations, and a Unichain CSP connect-src entry.
Plugin Registration & Activation
src/plugins/unichain/index.tsx, src/plugins/activePlugins.ts, src/context/PluginProvider/PluginProvider.tsx
Add Unichain plugin that constructs the ChainAdapter with getKnownTokens, and gate plugin activation by feature flag.
Feature Flags & UI Gating
src/state/slices/preferencesSlice/preferencesSlice.ts, src/constants/chains.ts, src/pages/Markets/components/MarketsRow.tsx, src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
Add Unichain feature flag, gate SECOND_CLASS_CHAINS and UI lists when disabled, and include Unichain asset in popular-assets when enabled.
Wallet & Account Handling
src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts, src/lib/account/evm.ts, src/state/slices/portfolioSlice/utils/index.ts
Gate wallet/account support for Unichain by feature flag and supportsUnichain capability.
Transaction Status & Utilities
src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx, src/lib/utils/unichain.ts
Add Unichain tx-status polling using getUnichainTransactionStatus; add utilities for chain-adapter detection and status mapping via ethers provider.
App Services & Coingecko Support
src/lib/asset-service/service/AssetService.ts, src/lib/coingecko/utils.ts, src/lib/market-service/coingecko/coingecko.test.ts
Filter assets by Unichain feature flag, include Unichain in Coingecko-supported IDs, update tests for new mapping.
Assets / Utilities & Misc
packages/utils/src/chainIdToFeeAssetId.ts, .../getAssetNamespaceFromChainId.ts, .../getChainShortName.ts, .../getNativeFeeAssetReference.ts, packages/utils/src/assetData/getBaseAsset.ts
Add Unichain-specific cases for fee asset, asset namespace, short name, and native fee reference.
State, Migrations & Tests
src/state/slices/opportunitiesSlice/mappings.ts, src/state/migrations/index.ts, src/test/mocks/store.ts, packages/caip/src/adapters/coingecko/utils.test.ts, src/vite-env.d.ts
Add Unichain entries to opportunity mapping, a new migration index, mockStore feature flag default, and test data updates.
Project Task / Plan
.beads/ss-dx5.8.json, .claude/plan.md
Add task entry for ss-dx5.8 and include Berachain-specific debug-trace fallback notes in plan doc.

Sequence Diagram(s)

sequenceDiagram
    participant PluginRegistry
    participant UnichainPlugin
    participant UnichainAdapter
    participant AssetService
    participant ViemClient
    participant UnichainNode

    PluginRegistry->>UnichainPlugin: register()
    UnichainPlugin->>UnichainAdapter: new ChainAdapter(rpcUrl, getKnownTokens)
    UnichainAdapter->>AssetService: getKnownTokens() (fetch assets)
    AssetService-->>UnichainAdapter: tokens list
    UnichainAdapter->>ViemClient: initialize client with rpcUrl
    ViemClient->>UnichainNode: http request -> RPC (VITE_UNICHAIN_NODE_URL)
    UnichainNode-->>ViemClient: RPC responses
    ViemClient-->>UnichainAdapter: client ready
    PluginRegistry-->>UnichainAdapter: adapter available to app
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

capy

Suggested reviewers

  • 0xApotheosis

Poem

🐰 I hopped through code with nimble paws,
Unichain stitched in without a pause.
Adapters, plugins, nodes aligned,
A shiny chain for users to find. ✨

🚥 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 clearly and specifically describes the main change: integrating Unichain as a second-class EVM chain via Relay, with the CAIP identifier eip155:130 included for clarity.

✏️ 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-unichain-relay-v2

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.

NeOMakinG and others added 17 commits February 17, 2026 21:45
The Unichain adapter.json (eip155_130) was created but not imported/exported
from the generated index.ts, causing coingeckoToAssetIds to not return Unichain.
The Sonic adapter.json (eip155_146) was created but not imported/exported
from the generated index.ts, preventing CoinGecko mapping for Sonic tokens.
…tle-relay

# Conflicts:
#	.env
#	.env.development
#	packages/caip/src/adapters/coingecko/generated/index.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/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/coingecko.ts
#	scripts/generateAssetData/generateAssetData.ts
#	src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
#	src/config.ts
#	src/constants/chains.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/pages/Markets/components/MarketsRow.tsx
#	src/state/slices/portfolioSlice/utils/index.ts
#	src/state/slices/preferencesSlice/preferencesSlice.ts
#	src/test/mocks/store.ts
#	src/vite-env.d.ts
Missing closing braces in 7 files where auto-resolve stripped
them at mantle/next-entry boundaries.

Also made generateChainRelatedAssetIndex self-contained (no
import from generateRelatedAssetIndex to avoid module-scope
ZERION_API_KEY check).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 Mantle assets added with relatedAssetKey cross-chain linking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nos-relay

# Conflicts:
#	.env
#	.env.development
#	headers/csps/index.ts
#	packages/caip/src/adapters/coingecko/generated/index.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/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/coingecko.ts
#	scripts/generateAssetData/generateAssetData.ts
#	src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
#	src/config.ts
#	src/constants/chains.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/pages/Markets/components/MarketsRow.tsx
#	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
…-relay

# Conflicts:
#	src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ic-relay

# Conflicts:
#	.env.development
#	packages/caip/src/adapters/coingecko/generated/index.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/index.ts
#	packages/chain-adapters/src/types.ts
#	packages/contracts/src/ethersProviderSingleton.ts
#	packages/contracts/src/viemClient.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/coingecko.ts
#	src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
#	src/config.ts
#	src/constants/chains.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/pages/Markets/components/MarketsRow.tsx
#	src/state/slices/portfolioSlice/utils/index.ts
#	src/state/slices/preferencesSlice/preferencesSlice.ts
#	src/test/mocks/store.ts
…chain-relay-v2

# Conflicts:
#	.beads/pr-context.jsonl
#	.claude/contracts/second-class-evm-chain.md
#	.env
#	.env.development
#	packages/caip/src/adapters/coingecko/generated/index.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/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
#	src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx
#	src/config.ts
#	src/constants/chains.ts
#	src/context/PluginProvider/PluginProvider.tsx
#	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/pages/Markets/components/MarketsRow.tsx
#	src/state/slices/opportunitiesSlice/mappings.ts
#	src/state/slices/portfolioSlice/utils/index.ts
#	src/state/slices/preferencesSlice/preferencesSlice.ts
#	src/test/mocks/store.ts
@gomesalexandre gomesalexandre marked this pull request as ready for review February 21, 2026 10:40
@gomesalexandre gomesalexandre requested a review from a team as a code owner February 21, 2026 10:40
…ale test counts

- Remove duplicate icon/networkIcon in Sonic baseAsset (merge artifact)
- Remove duplicate Sonic enum entry in CoingeckoAssetPlatform
- Remove duplicate katanaAssetId/megaethAssetId in generateRelatedAssetIndex
- Add unichainAssetId to generateChainRelatedAssetIndex ethAssetId array
- Add migration 297 for Unichain
- Fix coingecko.test.ts: remove duplicate assertions, increment counts for Unichain
- Add Sonic + Unichain type declarations to vite-env.d.ts
- Regenerate Unichain assets with updated related asset index

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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: 6

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

114-114: VITE_FEATURE_UNICHAIN key is out of alphabetical order.

The dotenv-linter reports [UnorderedKey]: VITE_FEATURE_UNICHAIN should be placed before VITE_FEATURE_WC_DIRECT_CONNECTION (line 103) to satisfy the linter. The feature flag itself is correct; this is purely an ordering nit.

🔧 Proposed fix (move the flag higher)
 VITE_FEATURE_WC_DIRECT_CONNECTION=true
 VITE_FEATURE_CETUS_SWAP=true
+VITE_FEATURE_UNICHAIN=true
 VITE_FEATURE_MANTLE=true
 ...
 VITE_FEATURE_SONIC=true
-VITE_FEATURE_UNICHAIN=true
 VITE_FEATURE_TON=true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.env.development at line 114, The VITE_FEATURE_UNICHAIN key is out of
alphabetical order per dotenv-linter; move the line defining
VITE_FEATURE_UNICHAIN so it appears before VITE_FEATURE_WC_DIRECT_CONNECTION
(and maintain any surrounding spacing/comments), ensuring the ENV keys remain
alphabetized and the file passes the linter.
packages/utils/src/getChainShortName.ts (1)

69-70: Consider a less ambiguous short name than 'UNI'.

'UNI' is the established ticker for Uniswap's governance token (a top-10 ERC-20). Since Unichain's native asset is ETH (not UNI), using this abbreviation for the chain badge could confuse users who see UNI next to a chain selector and associate it with the Uniswap token. Alternatives like 'UNCH' or 'UCH' avoid the collision.

🤖 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 69 - 70, Replace the
ambiguous short name for KnownChainIds.UnichainMainnet in getChainShortName:
instead of returning 'UNI' (which collides with Uniswap's ticker), return a less
ambiguous token such as 'UNCH' or 'UCH' so the chain badge won't be confused
with the Uniswap ERC‑20 symbol; update the return value in the case for
KnownChainIds.UnichainMainnet accordingly.
packages/utils/src/assetData/baseAssets.ts (1)

511-511: unichainChain breaks the naming convention for chain base-asset exports.

All other ETH-native L2 exports in this file use just the chain name: optimism, arbitrum, base, ink, linea, scroll, megaeth, katana. The new export is unichainChain instead of unichain, which is inconsistent and breaks downstream import ergonomics in consuming packages.

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

In `@packages/utils/src/assetData/baseAssets.ts` at line 511, The exported
constant unichainChain breaks the file's naming convention; rename the export to
unichain (replace export const unichainChain: Readonly<Asset> with export const
unichain: Readonly<Asset>) and update any local references or imports that use
unichainChain to the new symbol; ensure the Object.freeze({...}) initializer and
its contents remain unchanged and run tests/build to catch any remaining
references.
src/plugins/activePlugins.ts (1)

55-57: unichain is alphabetically misplaced in the array.

It's positioned between linea and litecoin but should appear after tron (before walletConnectToDapps). No functional impact — just a readability nit.

♻️ Proposed fix
   linea,
-  unichain,
   litecoin,
   ...
   tron,
+  unichain,
   walletConnectToDapps,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/activePlugins.ts` around lines 55 - 57, The array in
src/plugins/activePlugins.ts has the element "unichain" misplaced between
"linea" and "litecoin"; move the "unichain" entry so it appears after "tron" and
before "walletConnectToDapps" within the same array (the activePlugins list) to
restore alphabetical ordering and improve readability.
src/lib/utils/unichain.ts (1)

15-43: Consider caching JsonRpcProvider instances to avoid recreation overhead in polling loops.

getUnichainTransactionStatus creates a new JsonRpcProvider on every invocation. This function is called in useSendActionSubscriber within a polling loop to track transaction status, making repeated provider instantiation wasteful. The same pattern exists in katana.ts and hyperevm.ts—these utilities should all reuse provider instances per nodeUrl.

Extract a memoized provider factory:

♻️ Example: cache the provider per nodeUrl
+const providerCache = new Map<string, JsonRpcProvider>()
+
+const getOrCreateProvider = (nodeUrl: string): JsonRpcProvider => {
+  const cached = providerCache.get(nodeUrl)
+  if (cached) return cached
+  const provider = new JsonRpcProvider(nodeUrl, undefined, { staticNetwork: true })
+  providerCache.set(nodeUrl, provider)
+  return provider
+}
+
 export const getUnichainTransactionStatus = async (
   txHash: string,
   nodeUrl: string,
 ): Promise<TxStatus> => {
   try {
-    const provider = new JsonRpcProvider(nodeUrl, undefined, {
-      staticNetwork: true,
-    })
+    const provider = getOrCreateProvider(nodeUrl)
 
     const receipt = await provider.getTransactionReceipt(txHash)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/utils/unichain.ts` around lines 15 - 43, getUnichainTransactionStatus
is creating a new JsonRpcProvider on each call; extract and reuse providers by
implementing a simple memoized factory (e.g., getProviderForNode(nodeUrl)) that
caches JsonRpcProvider instances keyed by nodeUrl and returns the same provider
for repeated calls; update getUnichainTransactionStatus to call that factory
instead of new JsonRpcProvider, and apply the same pattern to katana.ts and
hyperevm.ts utilities to avoid repeated provider instantiation in polling loops.
packages/chain-adapters/src/evm/unichain/UnichainChainAdapter.ts (1)

40-46: Add explicit return type annotations to getDisplayName() and getName().

Both methods are missing explicit return types, which violates the project's strict typing guidelines.

📝 Proposed fix
-  getDisplayName() {
+  getDisplayName(): ChainAdapterDisplayName {
     return ChainAdapterDisplayName.Unichain
   }
 
-  getName() {
+  getName(): string {
     return 'Unichain'
   }

As per coding guidelines: "ALWAYS use explicit types for function parameters and return values in TypeScript."

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

In `@packages/chain-adapters/src/evm/unichain/UnichainChainAdapter.ts` around
lines 40 - 46, Add explicit return type annotations to the two methods: declare
getDisplayName(): ChainAdapterDisplayName and getName(): string. Update the
method signatures for getDisplayName and getName in UnichainChainAdapter to
include these return types (use the existing ChainAdapterDisplayName enum for
getDisplayName and string for getName) and ensure the implementations remain
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.beads/ss-dx5.8.json:
- Line 7: Update the JSON metadata so the PR tracking reflects current state:
change the "status" field value from "open" to "in-progress" (and ensure it will
be set to "done" on merge), and edit the "notes" checklist to mark completed
items as checked (replace relevant "[ ]" entries with "[x]" for the completed
items like chain-adapters and caip) so the "status" and checklist align with the
PR progress.

In @.claude/plan.md:
- Around line 1-33: Remove the tracked planning note file that is listed in
.gitignore by untracking it and committing the removal: run git rm --cached for
the tracked plan file, commit the deletion, and (optionally) delete the local
file so it is no longer in the repo while remaining ignored going forward;
ensure the file remains listed in .gitignore so future commits don’t re-add it.

In `@packages/chain-adapters/src/evm/mantle/MantleChainAdapter.ts`:
- Around line 18-20: Delete the duplicate isMantleChainAdapter type-guard in
MantleChainAdapter.ts and instead rely on the canonical implementation in
src/lib/utils/mantle.ts; remove the exported const isMantleChainAdapter from
this file and, if necessary, replace any local references with an import of the
util guard (the util guard performs null/undefined and typeof getChainId
checks), ensuring no other code in this module defines or exports another
isMantleChainAdapter.

In `@packages/chain-adapters/src/evm/unichain/index.ts`:
- Line 1: Remove the duplicate type guard definition isUnichainChainAdapter from
the UnichainChainAdapter file: delete the redundant function in
UnichainChainAdapter (the dead code) so the canonical type guard in
src/lib/utils/unichain.ts is the only implementation; ensure you do not alter
SecondClassEvmAdapter or UnichainChainAdapter class logic, and confirm the
remaining canonical isUnichainChainAdapter in utils performs proper
null/undefined checks and verifies required function/property signatures before
narrowing the type.

In `@packages/chain-adapters/src/evm/unichain/UnichainChainAdapter.ts`:
- Around line 18-20: Remove the dead/unsafe isUnichainChainAdapter function from
UnichainChainAdapter.ts; instead ensure the canonical guard lives only in
src/lib/utils/unichain.ts as the single source of truth, implemented defensively
by checking adapter != null, verifying typeof (adapter as ChainAdapter).getType
=== 'function', and then comparing (adapter as ChainAdapter).getType() to
KnownChainIds.UnichainMainnet; reference the ChainAdapter type and getType
method to locate usages and update imports if any code was pointing to the
removed function.

In `@packages/utils/src/assetData/baseAssets.ts`:
- Around line 501-504: The sonic object's literal contains duplicate properties
icon and networkIcon which violate no-dupe-keys and make the earlier entries
dead; remove the duplicated pair so only one icon and one networkIcon remain in
the sonic object (leave the correct/desired URL pair and delete the other),
ensuring the unique property names in the sonic object are declared once.

---

Nitpick comments:
In @.env.development:
- Line 114: The VITE_FEATURE_UNICHAIN key is out of alphabetical order per
dotenv-linter; move the line defining VITE_FEATURE_UNICHAIN so it appears before
VITE_FEATURE_WC_DIRECT_CONNECTION (and maintain any surrounding
spacing/comments), ensuring the ENV keys remain alphabetized and the file passes
the linter.

In `@packages/chain-adapters/src/evm/unichain/UnichainChainAdapter.ts`:
- Around line 40-46: Add explicit return type annotations to the two methods:
declare getDisplayName(): ChainAdapterDisplayName and getName(): string. Update
the method signatures for getDisplayName and getName in UnichainChainAdapter to
include these return types (use the existing ChainAdapterDisplayName enum for
getDisplayName and string for getName) and ensure the implementations remain
unchanged.

In `@packages/utils/src/assetData/baseAssets.ts`:
- Line 511: The exported constant unichainChain breaks the file's naming
convention; rename the export to unichain (replace export const unichainChain:
Readonly<Asset> with export const unichain: Readonly<Asset>) and update any
local references or imports that use unichainChain to the new symbol; ensure the
Object.freeze({...}) initializer and its contents remain unchanged and run
tests/build to catch any remaining references.

In `@packages/utils/src/getChainShortName.ts`:
- Around line 69-70: Replace the ambiguous short name for
KnownChainIds.UnichainMainnet in getChainShortName: instead of returning 'UNI'
(which collides with Uniswap's ticker), return a less ambiguous token such as
'UNCH' or 'UCH' so the chain badge won't be confused with the Uniswap ERC‑20
symbol; update the return value in the case for KnownChainIds.UnichainMainnet
accordingly.

In `@src/lib/utils/unichain.ts`:
- Around line 15-43: getUnichainTransactionStatus is creating a new
JsonRpcProvider on each call; extract and reuse providers by implementing a
simple memoized factory (e.g., getProviderForNode(nodeUrl)) that caches
JsonRpcProvider instances keyed by nodeUrl and returns the same provider for
repeated calls; update getUnichainTransactionStatus to call that factory instead
of new JsonRpcProvider, and apply the same pattern to katana.ts and hyperevm.ts
utilities to avoid repeated provider instantiation in polling loops.

In `@src/plugins/activePlugins.ts`:
- Around line 55-57: The array in src/plugins/activePlugins.ts has the element
"unichain" misplaced between "linea" and "litecoin"; move the "unichain" entry
so it appears after "tron" and before "walletConnectToDapps" within the same
array (the activePlugins list) to restore alphabetical ordering and improve
readability.

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.

lgtm - all CI green, contract review done.

prior testing confirmed on Unichain (native ETH balance, relay bridge quotes, chain selector). will re-verify on Soneium as final chain in the pipeline.

merge conflicts with develop (Cronos + Sonic) resolved cleanly - migration 297 added, related asset index updated, market service test counts bumped for ETH-native chains.

@gomesalexandre gomesalexandre merged commit a53f9fa into develop Feb 21, 2026
6 checks passed
@gomesalexandre gomesalexandre deleted the feat/integrate-unichain-relay-v2 branch February 21, 2026 11:06
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