Skip to content

feat: integrate zkSync Era (324) as second-class Relay chain#11934

Merged
gomesalexandre merged 8 commits intodevelopfrom
feat/integrate-zksync-relay
Feb 22, 2026
Merged

feat: integrate zkSync Era (324) as second-class Relay chain#11934
gomesalexandre merged 8 commits intodevelopfrom
feat/integrate-zksync-relay

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Feb 18, 2026

Description

Add support for zkSync Era (EVM chain, chainId 324) as a second-class citizen. zkSync Era is a ZK rollup Layer 2 with native ETH, using zero-knowledge proofs for security.

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

Implements: CAIP constants, chain adapter (SecondClassEvmAdapter), plugin, feature flag, Relay + Across swapper mappings, HDWallet support flags, CSP headers, asset generation script, viem/ethers client configuration, CoinGecko price feed integration, Zerion portfolio tracking, and all required shared-file entries.

Issue (if applicable)

Part of #11902

Risk

Low - All changes are behind the ZkSyncEra feature flag (VITE_FEATURE_ZK_SYNC_ERA), 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_ZK_SYNC_ERA=true in .env.development
  2. Run yarn dev
  3. Verify zkSync Era appears in chain selector
  4. Verify native ETH balance loads on zkSync Era
  5. Verify Relay and Across swap routes include zkSync Era
  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 zkSync Era support across the app: view/manage assets, swaps, market data, transaction status, and popular-assets discovery.
    • Integrated zkSync Era as an available plugin and enabled broad wallet support for zkSync Era transactions.
  • Chores

    • Added configuration and feature-flagging for zkSync Era, node endpoint support, asset metadata, and third-party data integrations.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

Warning

Rate limit exceeded

@gomesalexandre has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 5 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 feature-flagged zkSync Era (EVM chainId eip155:324) support across the app: CAIP constants, chain adapter, viem/ethers clients, HDWallet capability flags, swapper mappings, Coingecko mappings, asset-generation scripts, CSP and env config, plugin registration, feature flags, and related UI/state updates.

Changes

Cohort / File(s) Summary
Project Tracking & Metadata
\.beads/pr-context.jsonl, .beads/ss-dx5.*
Updated bead/task entries: several statuses changed to "open" and checklist items reset across multiple bead files.
Environment & CSP
.env, .env.development, src/config.ts, src/vite-env.d.ts, headers/csps/chains/zksyncera.ts, headers/csps/index.ts
Added VITE_ZKSYNC_ERA_NODE_URL and VITE_FEATURE_ZK_SYNC_ERA; added CSP for zksyncera and registered it.
CAIP Constants & Types
packages/caip/src/constants.ts, packages/types/src/base.ts, packages/types/src/zerion.ts
Introduced zkSyncEraAssetId / zkSyncEraChainId and KnownChainIds.ZkSyncEraMainnet; added mappings and Zerion entries.
Coingecko Adapter & Tests
packages/caip/src/adapters/coingecko/index.ts, packages/caip/src/adapters/coingecko/utils.ts, packages/caip/src/adapters/coingecko/*.test.ts
Added Coingecko platform/parse support for ZkSyncEra and updated tests to include ethOnZkSyncEra mappings.
Chain Adapters & Types
packages/chain-adapters/src/evm/EvmBaseAdapter.ts, packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts, packages/chain-adapters/src/types.ts, packages/chain-adapters/src/evm/index.ts
Registered ZkSyncEra in evmChainIds, support assertions, network metadata, and adapter exports; extended adapter/type mappings.
ZkSync Era Chain Adapter
packages/chain-adapters/src/evm/zksyncera/ZkSyncEraChainAdapter.ts, packages/chain-adapters/src/evm/zksyncera/index.ts
Added new ChainAdapter implementation for ZkSync Era with BIP44 params, display/name/type/fee asset wiring and exported types/guards.
Viem / Ethers Clients
packages/contracts/src/viemClient.ts, packages/contracts/src/ethersProviderSingleton.ts
Added viem/ethers client registration for ZkSync Era and RPC URL lookup via VITE_ZKSYNC_ERA_NODE_URL.
HDWallet Capability Flags & Guards
packages/hdwallet-*/src/*.ts (coinbase, gridplus, keepkey, ledger, metamask-multichain, native, phantom, trezor, vultisig, walletconnectv2), packages/hdwallet-core/src/ethereum.ts, packages/hdwallet-core/src/wallet.ts
Added _supportsZkSyncEra flags across wallets and a supportsZkSyncEra type guard in core.
Swapper Mappings & Token Utils
packages/swapper/src/swappers/*/constant.ts, packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
Mapped zkSyncEraChainId to viem zksync network id for Across/Relay; added native-asset mapping for ZkSync Era.
Asset Data & Generation
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, scripts/generateAssetData/*, scripts/generateAssetData/zksyncera/index.ts
Added zkSync Era base asset, explorer metadata handling, included zksyncera assets in generation pipeline and related asset indices.
App Feature Flags & Constants
src/constants/chains.ts, src/state/slices/preferencesSlice/preferencesSlice.ts, src/state/slices/opportunitiesSlice/mappings.ts, src/test/mocks/store.ts
Added ZkSyncEraMainnet to SECOND_CLASS_CHAINS; added FeatureFlags.ZkSyncEra and initial mock flag; added empty opportunities mapping.
Plugin System & Registration
src/plugins/zksyncera/index.tsx, src/plugins/activePlugins.ts
New zksyncera plugin registering a chain adapter factory that uses asset service for known tokens and config RPC URL; plugin added to activePlugins.
App Logic, Hooks & Utilities
src/hooks/useWalletSupportsChain/*, src/lib/account/evm.ts, src/lib/utils/zksyncera.ts, src/lib/coingecko/utils.ts, src/lib/asset-service/service/AssetService.ts
Feature-flagged inclusion of zkSync Era in wallet support checks, account derivation, coingecko supported chain list, asset filtering; added utilities for adapter detection and tx status via RPC.
UI & Market Updates
src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx, src/pages/Markets/components/MarketsRow.tsx
Feature-flag gated addition of zkSync Era asset to popular assets and MarketsRow chain filtering dependency.
State & Migrations
src/state/migrations/index.ts
Added migration entry 302: clearAssets.
Portfolio & Preferences
src/state/slices/portfolioSlice/utils/index.ts, src/state/slices/preferencesSlice/preferencesSlice.ts
Account labeling and wallet-support checks extended to zkSync Era; preferences initial state wired to new feature flag.
Tests
src/lib/market-service/coingecko/coingecko.test.ts, packages/caip/src/adapters/coingecko/*.test.ts
Updated expectations to include new zkSync Era asset keys and counts in coingecko-related tests.

Sequence Diagram(s)

sequenceDiagram
  participant App as App (PluginProvider)
  participant Plugin as zksyncera Plugin
  participant AssetSvc as AssetService
  participant Adapter as ZkSyncEraChainAdapter
  participant Viem as viemZkSyncEraClient
  participant Wallet as HDWallet

  App->>Plugin: register() (feature flag check)
  Plugin->>AssetSvc: getAssets() (filter by zkSync Era)
  AssetSvc-->>Plugin: tokens list
  Plugin->>Adapter: construct(rpcUrl, getKnownTokens)
  Adapter->>Viem: use viemZkSyncEraClient (RPC calls)
  Wallet->>Adapter: supportsZkSyncEra? (capability flag)
  Adapter-->>Wallet: returns adapter instance (if supported)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 A hop for code and chain, I cheer,

zkSync Era now draws near,
Constants set and adapters sewn,
Tokens found and RPC shown,
Flags flipped on—a rabbit's cheer! ✨

🚥 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 PR title clearly and specifically describes the main change: integrating zkSync Era as a second-class Relay chain, with the chain identifier (324) provided 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-zksync-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 2 commits February 22, 2026 17:56
Blast's public RPC rate-limits debug_traceTransaction to 0/sec from
browser origins. Skip it entirely (like hyperEVM) and fall through to
the WETH Withdrawal event fallback, which reliably detects ETH received
from Across/Relay SpokePool fills (SpokePool always calls WETH.withdraw()
before sending native ETH to recipient).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre marked this pull request as ready for review February 22, 2026 16:56
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.

Does what it says on the box.

Tested World Chain, Blast, and zkSync Era - all happy: https://jam.dev/c/9163ecc7-52c6-4f1e-a413-11d15c1da35a

Also includes fix for Blast execution price not showing post-swap: Blast's public RPC rate-limits debug_traceTransaction to 0/sec from browser origins, so we skip it entirely (like HyperEVM) and fall through to the WETH Withdrawal event fallback - which reliably detects ETH received from Across/Relay SpokePool fills since SpokePool always calls WETH.withdraw() before sending native ETH to recipient.

@gomesalexandre gomesalexandre enabled auto-merge (squash) February 22, 2026 16:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/SecondClassEvmAdapter.ts`:
- Around line 408-410: The early-return guard in fetchInternalTransactions
currently excludes hyperEvmChainId and blastChainId but misses zkSyncEraChainId,
causing extractCalls(trace) to receive an array-shaped debug_traceTransaction
result and fail to extract internals; update the guard in
fetchInternalTransactions to include zkSyncEraChainId alongside hyperEvmChainId
and blastChainId so the function returns [] early for zkSync Era traces (this
aligns with the WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID handling).

zksync era returns trace in an array-wrapped structure unlike standard
evm, causing extractCalls to silently fail. skip it like blast/hyperevm
and fall through to the weth withdrawal fallback.

Co-Authored-By: Claude Sonnet 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.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts`:
- Line 17: No code change required; the additions for zkSyncEra are correct —
ensure the import zkSyncEraChainId is present, the WETH address
0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91 is added to the chain map, and the
parseTx guard that skips debug_traceTransaction for zkSyncEra (matching the
existing logic for blastChainId and hyperEvmChainId) remains so the WETH
withdrawal log fallback is used; verify these symbols (zkSyncEraChainId, the
WETH address entry, parseTx, debug_traceTransaction, blastChainId,
hyperEvmChainId) are consistent with the established pattern and approve the
changes.

@gomesalexandre gomesalexandre merged commit afb31b3 into develop Feb 22, 2026
6 checks passed
@gomesalexandre gomesalexandre deleted the feat/integrate-zksync-relay branch February 22, 2026 17:37
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