Skip to content

feat: integrate World Chain (480) as second-class Relay chain#11932

Merged
gomesalexandre merged 11 commits intodevelopfrom
feat/integrate-worldchain-relay
Feb 22, 2026
Merged

feat: integrate World Chain (480) as second-class Relay chain#11932
gomesalexandre merged 11 commits intodevelopfrom
feat/integrate-worldchain-relay

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Feb 18, 2026

Description

Integrates World Chain (chainId: 480) as a second-class citizen EVM chain via Relay.link.

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

World Chain is an OP Stack L2 with native ETH. This adds full support including:

  • HDWallet support (native, Ledger, MetaMask, WalletConnect, etc.)
  • Chain adapter + plugin registration
  • CoinGecko price feed integration
  • Relay + Across swapper support
  • Zerion portfolio tracking
  • Feature flag: WorldChain

How to Test

  1. Enable the World Chain feature flag at /flags
  2. Connect a wallet
  3. Verify World Chain appears in chain selector
  4. Verify ETH balance shows for World Chain

Related Issues

Closes part of #11902

Summary by CodeRabbit

  • New Features
    • World Chain network integration: users can enable the World Chain feature flag to connect compatible wallets, view/manage World Chain assets, and trade on World Chain.
    • Asset listings and market data now include World Chain tokens when the feature is enabled.
    • Wallet and swap tooling updated to support network discovery, token lookups, and transaction status for World Chain.

@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 26 minutes and 0 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 WorldChain (eip155:480) as a gated second‑class EVM chain across configuration, CAIP/constants, adapters, viem/ethers clients, HDWallet capability flags, asset generation, swappers, plugin registration, UI feature‑gating, and utilities.

Changes

Cohort / File(s) Summary
Env & Config
.env, .env.development, src/config.ts
Add VITE_WORLDCHAIN_NODE_URL and VITE_FEATURE_WORLDCHAIN with validation and env-specific defaults.
CSPs
headers/csps/chains/worldchain.ts, headers/csps/index.ts
New CSP entry referencing the WorldChain RPC URL; registered in CSP index.
CAIP & Types
packages/caip/src/constants.ts, packages/types/src/base.ts, packages/types/src/zerion.ts
Introduce worldChainAssetId/worldChainChainId, CHAIN_REFERENCE.WorldChainMainnet (480), and expose KnownChainIds.WorldChainMainnet; add Zerion mapping.
Chain Adapters & Plugins
packages/chain-adapters/src/evm/..., src/plugins/worldchain/index.tsx, src/plugins/activePlugins.ts
New WorldChain ChainAdapter module, re-export in evm index, plugin registering adapter using VITE_WORLDCHAIN_NODE_URL; adapter metadata and token getter added.
RPC / Clients
packages/contracts/src/viemClient.ts, packages/contracts/src/ethersProviderSingleton.ts, packages/swap-widget/src/components/SwapWidget.tsx
Create viemWorldChainClient, wire VITE_WORLDCHAIN_NODE_URL into RPC resolver and viem client mappings; add worldchain to VIEM chains map.
HDWallet support & guards
packages/hdwallet-core/src/*, multiple hdwallet implementations (ledger, trezor, gridplus, etc.)
Add _supportsWorldChain flag to HDWallet interface and implementations; add supportsWorldChain type guard; set per-wallet capability flags.
Swapper mappings & Relay
packages/swapper/src/swappers/..., packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
Map worldChainChainId to viem worldchain.id for Across/Relay; handle relayTokenToAssetId case for WorldChainMainnet.
Asset & Coingecko wiring
packages/utils/src/assetData/*, packages/caip/src/adapters/coingecko/*, scripts/generateAssetData/*
Add worldchain base asset, Coingecko platform mapping and parsing support, new worldchain asset generator module, include worldchain assets in asset generation and related-asset indices; update tests.
Utilities & Helpers
src/lib/utils/worldchain.ts, packages/utils/src/*
Add worldchain utilities: isWorldChainChainAdapter and getWorldChainTransactionStatus; add fee asset/namespace/short-name mappings and fee-asset resolution.
UI, state & gating
src/constants/chains.ts, src/context/PluginProvider/PluginProvider.tsx, src/hooks/useWalletSupportsChain/*, src/lib/*, src/pages/*, src/state/slices/*, src/components/TradeAssetSearch/hooks/*, src/test/mocks/store.ts
Add feature-flag gating (WorldChain) across knownChainIds, supportedChains, wallet capability checks, asset filtering, popular-assets inclusion, preferences default flag, and test mock updates.
Misc / Build scripts
scripts/generateAssetData/worldchain/index.ts, .beads/ss-dx5.14.json
Add generation helper for worldchain assets and new bead/task JSON documenting the integration plan and dependencies.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Client(UI)
  participant Plugin as WorldChainPlugin
  participant AssetSvc as AssetService/Coingecko
  participant Adapter as WorldChainChainAdapter
  participant Wallet as HDWallet
  participant RPC as WorldChain RPC

  UI->>Plugin: register() (on startup)
  Plugin->>Adapter: construct(rpcUrl)
  UI->>AssetSvc: request known tokens (via adapter.getKnownTokens)
  Adapter->>AssetSvc: query assets where chainId == worldChainChainId
  AssetSvc-->>Adapter: return token list
  UI->>Wallet: ask supportsWorldChain?
  Wallet-->>UI: true/false
  UI->>Adapter: submit tx or check tx status
  Adapter->>RPC: eth_getTransactionReceipt (VITE_WORLDCHAIN_NODE_URL)
  RPC-->>Adapter: receipt (status)
  Adapter-->>UI: mapped TxStatus
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰✨ A curious rabbit hops to say,
WorldChain joins the chainyard play.
Nodes and plugins, wallets aligned,
Tokens found and RPCs signed —
Hoppy hops to new lands today! 🌍

🚥 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 concisely summarizes the main change: integrating World Chain (chainId 480) as a second-class Relay chain. It directly reflects the primary objective of this changeset.

✏️ 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-worldchain-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 13:01
…ldchain-relay

# Conflicts:
#	.beads/pr-context.jsonl
#	.beads/ss-dx5.10.json
#	.beads/ss-dx5.8.json
#	.beads/ss-dx5.9.json
#	.claude/contracts/second-class-evm-chain.md
#	.env
#	.env.development
#	headers/csps/index.ts
#	packages/caip/src/adapters/coingecko/generated/index.ts
#	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/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/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/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
- yarn generate:chain eip155:480 - 29 tokens discovered
- Add worldChainChainId to WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID
- Add worldChainAssetId to generateChainRelatedAssetIndex ETH array
- Fix duplicate starknetAssetId import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre marked this pull request as ready for review February 22, 2026 12:06
Unichain, Bob, Mode had duplicate networkIcon entries from merge
conflict resolution. Keep newer develop versions.

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

Caution

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

⚠️ Outside diff range comments (1)
src/lib/market-service/coingecko/coingecko.test.ts (1)

228-269: ⚠️ Potential issue | 🔴 Critical

Duplicate destructuring identifiers and duplicate assertion entries — TypeScript error + incorrect assertions.

Lines 234–239 (new additions) introduce bindings already declared by lines 240–248 (pre-existing):

Duplicate name New line Existing line
ethOnMegaEthKey 235, 237 244
ethOnHemiKey 236 241
ethOnLineaKey 238 242
ethOnBobKey 239 240

TypeScript reports Duplicate identifier for duplicate names within the same destructuring binding, so this file will not compile. The ethAssetId expected array (lines 256–269) also carries both the new and old occurrences of these names as separate array entries, making the assertion itself incorrect.

The fix is to remove or replace the stale (pre-existing) bindings/entries with the new WorldChain-aware ones and keep the array length consistent with the corrected count expectations above.

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

In `@src/lib/market-service/coingecko/coingecko.test.ts` around lines 228 - 269,
The test introduces duplicate destructuring identifiers and mismatched expected
arrays: clean up the Object.keys(result) destructuring to use unique identifiers
(remove the stale pre-existing bindings and keep the WorldChain-aware names such
as ethOnWorldChainKey, ethOnMegaEthKey, ethOnHemiKey, ethOnLineaKey,
ethOnBobKey, etc.), then update the btcAssetId and ethAssetId expectation arrays
to reference exactly those unique destructured variables (no duplicates) so the
length and contents align with the keys you actually destructured.
🧹 Nitpick comments (1)
src/lib/utils/worldchain.ts (1)

19-22: Consider caching the JsonRpcProvider to avoid creating a new instance per call.

A fresh JsonRpcProvider is instantiated on every invocation. Since getWorldChainTransactionStatus is likely called in a polling loop, this allocates a new connection each time. packages/contracts/src/ethersProviderSingleton.ts (already in the import graph for this module) may offer a reusable pattern, or a module-level cached provider keyed on nodeUrl would avoid the overhead.

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

In `@src/lib/utils/worldchain.ts` around lines 19 - 22,
getWorldChainTransactionStatus currently creates a new JsonRpcProvider on every
call; change this to reuse a cached provider instance instead (either use the
existing ethersProviderSingleton pattern from
packages/contracts/src/ethersProviderSingleton.ts or implement a simple
module-level Map keyed by nodeUrl that stores JsonRpcProvider instances). Update
getWorldChainTransactionStatus to retrieve the provider from that cache
(creating and storing it only if missing) rather than instantiating new
JsonRpcProvider each invocation, and ensure the cache key is nodeUrl so
different nodes get distinct providers.
🤖 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.development:
- Line 64: Replace the invalid Tenderly URL value for VITE_WORLDCHAIN_NODE_URL
so it either includes the required Tenderly access key placeholder or, better,
uses the public Alchemy endpoint; specifically update the
VITE_WORLDCHAIN_NODE_URL entry (the environment variable name
VITE_WORLDCHAIN_NODE_URL) to a working URL such as the Alchemy public endpoint
"https://worldchain-mainnet.g.alchemy.com/public" or to the Tenderly pattern
with a placeholder token
("https://worldchain-mainnet.gateway.tenderly.co/$TENDERLY_NODE_ACCESS_KEY") so
developers have a usable default and know where to supply the access key.
- Line 64: Update the VITE_WORLDCHAIN_NODE_URL environment variable value:
replace the current Tenderly gateway URL set in VITE_WORLDCHAIN_NODE_URL with
World Chain's official public RPC endpoint
"https://worldchain-mainnet.g.alchemy.com/public" so the variable
VITE_WORLDCHAIN_NODE_URL points to the official World Chain RPC.

In `@packages/utils/src/assetData/baseAssets.ts`:
- Around line 553-554: In the frozen asset objects unichainChain, bobChain, and
modeChain remove the duplicated networkIcon property so each
Object.freeze({...}) contains only one networkIcon entry; locate the duplicate
keys in baseAssets.ts (the newly added networkIcon lines) and delete those extra
networkIcon lines, leaving the original/correct networkIcon values intact for
unichainChain, bobChain, and modeChain.

In `@src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx`:
- Around line 3-10: The import block in useGetPopularAssetsQuery.tsx contains
duplicate named bindings (berachainAssetId, bobAssetId, cronosAssetId,
hemiAssetId) which causes a TS2300 compile error; open the import statement that
references these identifiers and remove the repeated occurrences so each named
import appears only once, leaving a single berachainAssetId, bobAssetId,
cronosAssetId, and hemiAssetId in the { ... } list.

In `@src/lib/market-service/coingecko/coingecko.test.ts`:
- Around line 172-175: There are duplicate assertions checking
Object.keys(result).length in the same test blocks; remove the stale/earlier
expect calls and keep only the final expected count. In coingecko.test.ts,
inside the test that currently has three expects for Object.keys(result).length
(values 7, 13, 14), delete the two older expects and leave a single
expect(Object.keys(result).length).toEqual(14); do the same in the 'can return
some results if partially rate limited' test (remove the earlier counts and keep
only the final expected value used by that test). Ensure each it block contains
only one length assertion using Object.keys(result).length and the correct final
number.

In `@src/lib/utils/worldchain.ts`:
- Around line 39-41: Replace the direct console.error call in the catch block of
the getTransactionStatus flow with the project's structured logger (e.g.,
logger.error or processLogger.error) so the error goes through ShapeShift's
logging infra; include the caught error object and relevant contextual metadata
(transaction hash/txId, network, and function name) in the structured log, then
continue to return TxStatus.Unknown as before. Ensure you import/obtain the
module logger used elsewhere in this file and use the logger.error method with a
descriptive message plus the error and context fields.

---

Outside diff comments:
In `@src/lib/market-service/coingecko/coingecko.test.ts`:
- Around line 228-269: The test introduces duplicate destructuring identifiers
and mismatched expected arrays: clean up the Object.keys(result) destructuring
to use unique identifiers (remove the stale pre-existing bindings and keep the
WorldChain-aware names such as ethOnWorldChainKey, ethOnMegaEthKey,
ethOnHemiKey, ethOnLineaKey, ethOnBobKey, etc.), then update the btcAssetId and
ethAssetId expectation arrays to reference exactly those unique destructured
variables (no duplicates) so the length and contents align with the keys you
actually destructured.

---

Nitpick comments:
In `@src/lib/utils/worldchain.ts`:
- Around line 19-22: getWorldChainTransactionStatus currently creates a new
JsonRpcProvider on every call; change this to reuse a cached provider instance
instead (either use the existing ethersProviderSingleton pattern from
packages/contracts/src/ethersProviderSingleton.ts or implement a simple
module-level Map keyed by nodeUrl that stores JsonRpcProvider instances). Update
getWorldChainTransactionStatus to retrieve the provider from that cache
(creating and storing it only if missing) rather than instantiating new
JsonRpcProvider each invocation, and ensure the cache key is nodeUrl so
different nodes get distinct providers.

gomesalexandre and others added 2 commits February 22, 2026 13:22
- Replace Tenderly RPC (requires API key) with Alchemy public endpoint
- Remove duplicate imports in useGetPopularAssetsQuery
- Remove duplicate expect assertions in coingecko market service test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Chainlist.org as fallback RPC source + curl verification step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gomesalexandre and others added 2 commits February 22, 2026 13:36
Merge artifact left duplicate ethOnMegaEthKey, ethOnBobKey, ethOnHemiKey,
ethOnLineaKey declarations. Correct order: bob, worldchain, hemi, linea.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove duplicate destructuring variables from merge
- Fix ethOnBob/ethOnWorldChain ordering to match adapter registration
- Bump flatten/rate-limited counts for World Chain (+1 each)

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

all checks green, contract review passes, lgtm

@gomesalexandre gomesalexandre merged commit d371209 into develop Feb 22, 2026
6 checks passed
@gomesalexandre gomesalexandre deleted the feat/integrate-worldchain-relay branch February 22, 2026 12:49
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.

all gucci, CI green across the board 🫡

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