Skip to content

feat: integrate Cronos (chainId 25) as second-class EVM chain#11910

Merged
gomesalexandre merged 35 commits intodevelopfrom
feat/integrate-cronos-relay
Feb 21, 2026
Merged

feat: integrate Cronos (chainId 25) as second-class EVM chain#11910
gomesalexandre merged 35 commits intodevelopfrom
feat/integrate-cronos-relay

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Feb 17, 2026

Description

Add support for Cronos (EVM L1, chainId 25) as a second-class citizen. Cronos is an EVM-compatible L1 blockchain with CRO as the native gas token.

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

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

Implements: CAIP constants, chain adapter, plugin, feature flag, Relay swapper mapping, HDWallet support flags, CSP headers, asset generation script, and all required shared-file entries.

Issue (if applicable)

Part of #11902

Risk

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

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

Testing

Engineering

  1. Set VITE_FEATURE_CRONOS=true in .env.development
  2. Run yarn dev
  3. Verify Cronos appears in chain selector
  4. Verify native CRO balance loads on Cronos
  5. Verify Relay swap routes include Cronos

Operations

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

Summary by CodeRabbit

  • New Features

    • Added support for the Cronos blockchain network, enabling users to manage assets, trade, and interact with the Cronos ecosystem directly within the platform.
  • Chores

    • Updated environment configuration and documentation to support new blockchain integration.

…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
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Walkthrough

This pull request implements comprehensive support for the Cronos blockchain (chainId 25) across the entire ShapeShift ecosystem. The integration includes CAIP constants, EVM chain adapters, wallet capability flags, asset data generation, feature gating, plugin registration, transaction status utilities, and configuration setup.

Changes

Cohort / File(s) Summary
Configuration & Environment
.env, .env.development, src/config.ts, src/vite-env.d.ts, .gitignore
Added environment variables VITE_CRONOS_NODE_URL (with default and development values) and VITE_FEATURE_CRONOS with validators. Updated .gitignore for ephemeral Claude plans.
CAIP Constants & Types
packages/caip/src/constants.ts, packages/types/src/base.ts, packages/types/src/zerion.ts
Introduced cronosAssetId, cronosChainId constants, CronosMainnet to CHAIN_REFERENCE, updated VALID_CHAIN_IDS and FEE_ASSET_IDS. Extended type unions to include CronosMainnet and updated Zerion chain mappings.
Coingecko Adapter Integration
packages/caip/src/adapters/coingecko/index.ts, packages/caip/src/adapters/coingecko/utils.ts, packages/caip/src/adapters/coingecko/utils.test.ts
Added Cronos to CoingeckoAssetPlatform enum, wired bidirectional mappings between Cronos and chainId, extended asset parsing to handle Cronos platform tokens.
EVM Chain Adapters
packages/chain-adapters/src/evm/EvmBaseAdapter.ts, packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts, packages/chain-adapters/src/evm/cronos/CronosChainAdapter.ts, packages/chain-adapters/src/evm/cronos/index.ts, packages/chain-adapters/src/evm/index.ts
Registered CronosMainnet in EVM chain IDs, added chain capability routing, created Cronos-specific adapter extending SecondClassEvmAdapter with BIP44 parameters and asset/RPC configuration.
Type Mappings
packages/chain-adapters/src/types.ts
Extended ChainSpecificAccount, ChainSpecificFeeData, ChainSignTx, ChainSpecificBuildTxData, ChainSpecificGetFeeDataInput type mappings to include CronosMainnet; added Cronos to ChainAdapterDisplayName enum.
Contract Clients
packages/contracts/src/ethersProviderSingleton.ts, packages/contracts/src/viemClient.ts
Added rpcUrlByChainId case for CronosMainnet, created viemCronosClient, extended viemClientByChainId and viemNetworkIdByChainId mappings with Cronos references.
Wallet Provider Capabilities
packages/hdwallet-core/src/ethereum.ts, packages/hdwallet-core/src/wallet.ts, packages/hdwallet-coinbase/src/coinbase.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 _supportsCronos capability flag to all wallet implementations (set to true for GridPlus, Ledger, MetaMask, Native, Trezor, WalletConnectV2; false for Coinbase, KeepKey, Phantom, Vultisig). Created supportsCronos type guard in wallet.ts.
Asset Data & Base Assets
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
Exported cronos asset constant with metadata (icon, explorer, symbol CRO). Extended getBaseAsset, chainIdToFeeAssetId, asset namespace, and chain short name utilities with Cronos routing logic.
Asset Generation Scripts
scripts/generateAssetData/coingecko.ts, scripts/generateAssetData/cronos/index.ts, scripts/generateAssetData/generateAssetData.ts, scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts
Added Cronos asset fetching via coingecko, created cronos module to fetch and unfreeze assets, integrated into asset data generation pipeline. Added manual related asset mapping linking Ethereum CRO (erc20:0xa0b73e1ff0b80914ab6fe0444e65848c4c34450b) to Cronos CRO (slip44:60).
Feature Flags & State
src/state/slices/preferencesSlice/preferencesSlice.ts, src/state/slices/opportunitiesSlice/mappings.ts, src/state/migrations/index.ts, src/test/mocks/store.ts, src/constants/chains.ts
Added Cronos to FeatureFlags type and initialized from config. Gated CronosMainnet in SECOND_CLASS_CHAINS and knownChainIds behind enabledFlags.Cronos. Added empty DeFi opportunities mapping and migration entry 295.
Plugin Registration
src/plugins/cronos/index.tsx, src/plugins/activePlugins.ts
Created cronos plugin that registers ChainAdapter with RPC URL and getKnownTokens resolver. Added cronos to activePlugins export array.
Utilities & Hooks
src/lib/utils/cronos.ts, src/lib/coingecko/utils.ts, src/lib/account/evm.ts, src/lib/asset-service/service/AssetService.ts, src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts, src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
Created Cronos utility module with isCronosChainAdapter type guard and getCronosTransactionStatus (JSON-RPC eth_getTransactionReceipt polling). Extended coingecko supported chains, EVM account derivation, asset service filtering, wallet chain support checks, and transaction status polling with Cronos logic.
UI Components & Pages
src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx, src/pages/Markets/components/MarketsRow.tsx
Added cronosAssetId to popular assets when feature flag enabled. Extended market row filtering to gate CronosMainnet behind Cronos feature flag.
Relay & Swapper
packages/swapper/src/swappers/RelaySwapper/constant.ts, packages/swapper/src/swappers/RelaySwapper/utils/relayTokenToAssetId.ts
Extended chainIdToRelayChainId mapping for Cronos. Added CronosMainnet case to relayTokenToAssetId switch statement.
CSP Headers
headers/csps/chains/cronos.ts, headers/csps/index.ts
Created Cronos CSP configuration exporting connect-src directive with VITE_CRONOS_NODE_URL. Added cronos import and export to CSP index.
Developer Documentation
.beads/ss-dx5.4.json, .claude/contracts/second-class-evm-chain.md, .claude/skills/chain-integration/SKILL.md, AGENTS.md, CLAUDE.md
Added task definition for Cronos integration under parent epic ss-dx5. Updated second-class EVM chain contract with feature flag and URL validation details, manual related asset index guidance. Added developer workflow documentation for issue tracking, session completion, and pre-push lint requirements.
Build Configuration
package.json
Increased Node.js memory limit for type-check script to 8GB (NODE_OPTIONS=--max-old-space-size=8192).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • shapeshift/web#11918: Implements identical second-class EVM chain integration pattern for Berachain across the same modules and functions.
  • shapeshift/web#11569: Adds Katana chain support using the same code paths and file modifications as this Cronos integration.
  • shapeshift/web#11956: Implements the second-class EVM chain integration specification documented in .claude/contracts/second-class-evm-chain.md that governs these changes.

Suggested labels

capy

Poem

🐰 A hop across the cosmos wide,
Cronos joins the relay ride!
CRO tokens bounce with glee,
Wallets sync in harmony—
slip44:60 marks the way,
ShapeShift grows another day! 🌟

🚥 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 pull request title clearly and concisely describes the main change: integrating Cronos as a second-class EVM chain with chainId 25, which is the primary objective of the changeset.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/integrate-cronos-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.

NeOMakinG and others added 17 commits February 17, 2026 15:38
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
…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>
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.

Happy camper generally but only 2 popular assets - happy on search though. Probably a similar fix as other second-class evm chains PRs.

Also same bug as cross-swap TO CRO present with relay, same wrapped-native asset issue as others

https://jam.dev/c/6109e7ac-37e9-4f43-84de-12b6868399ff

Cronos (receive) side Tx cronoscan.com/tx/0xec233afcac26adcac06b68f83df288fac37edc5e7963837e3e01df8a97ea3b1d

gomesalexandre and others added 5 commits February 20, 2026 15:40
…ract

- Replace Berachain-only WBERA burn detection with generalized
  WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID mapping in SecondClassEvmAdapter
- Add WMNT address for Mantle cross-chain swap native receives
- Fix Linea networkIcon URL (CoinGecko 403 -> relay.link CDN)
- Update second-class-evm-chain contract with wrapped native,
  icon validation, and append-only convention sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gomesalexandre and others added 3 commits February 20, 2026 19:59
Emulates squash merge of #11905 into develop.

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

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.

happy on all counts - cronos sends, swaps (both directions), tx history, execution price, popular assets, CRO cross-chain relation all working

https://jam.dev/c/9634e466-e766-49f8-988d-65d755a874db

@gomesalexandre gomesalexandre enabled auto-merge (squash) February 20, 2026 19:33
gomesalexandre and others added 2 commits February 20, 2026 20:48
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gomesalexandre added a commit that referenced this pull request Feb 20, 2026
Emulates squash merge of #11910 into develop.

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

🧹 Nitpick comments (3)
src/plugins/cronos/index.tsx (1)

22-36: fromAssetId is called twice per asset — optional single-pass refactor.

fromAssetId(asset.assetId) is invoked in the .filter() predicate and again in .map() to extract assetReference. These can be merged into one pass to avoid redundant parsing.

♻️ Combine filter + map into a single reduce pass
-                return assetService.assets
-                    .filter(asset => {
-                      const { chainId, assetNamespace } = fromAssetId(asset.assetId)
-                      return chainId === cronosChainId && assetNamespace === 'erc20'
-                    })
-                    .map(asset => ({
-                      assetId: asset.assetId,
-                      contractAddress: fromAssetId(asset.assetId).assetReference,
-                      symbol: asset.symbol,
-                      name: asset.name,
-                      precision: asset.precision,
-                    }))
+                return assetService.assets.reduce<
+                  Array<{ assetId: string; contractAddress: string; symbol: string; name: string; precision: number }>
+                >((acc, asset) => {
+                  const { chainId, assetNamespace, assetReference } = fromAssetId(asset.assetId)
+                  if (chainId === cronosChainId && assetNamespace === 'erc20') {
+                    acc.push({
+                      assetId: asset.assetId,
+                      contractAddress: assetReference,
+                      symbol: asset.symbol,
+                      name: asset.name,
+                      precision: asset.precision,
+                    })
+                  }
+                  return acc
+                }, [])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/cronos/index.tsx` around lines 22 - 36, getKnownTokens currently
calls fromAssetId(asset.assetId) twice per asset (once in the .filter predicate
and again in .map), causing redundant work; update getKnownTokens to parse each
asset's id once (e.g., use a single .reduce over assetService.assets or first
.map to include parsed = fromAssetId(asset.assetId) then filter on
parsed.chainId/assetNamespace and return the final object using
parsed.assetReference) so you only call fromAssetId once per asset; target the
getKnownTokens function and the use of fromAssetId, assetService.assets, and the
filter/map logic when making this change.
scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts (1)

276-285: Optional: remove now-unreachable return at Line 285.

The recovery block (Lines 277–282) handles the sole remaining case (!group), making the trailing return on Line 285 dead code. The three mutually exclusive guards now cover every possible state of group:

Condition Handled by
group && includes Line 264
group && !includes Line 272
!group Lines 277–282 (new)
♻️ Proposed cleanup
     // Group absent from index but asset has a relatedAssetKey - recover by creating the group
     if (!group) {
       console.log(
         `Recovering orphaned relatedAssetKey for ${assetId}: creating group ${existingRelatedAssetKey}`,
       )
       relatedAssetIndex[existingRelatedAssetKey] = [assetId]
       return
     }
-
-    return
   }
🤖 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 276 - 285, Remove the now-unreachable trailing "return" after the
orphan recovery block in generateChainRelatedAssetIndex: the code paths for
group && includes, group && !includes, and !group (the recovery that sets
relatedAssetIndex[existingRelatedAssetKey] = [assetId]) already cover all cases,
so delete the redundant return statement that follows that block (the lone
"return" after handling !group involving group, assetId,
existingRelatedAssetKey, and relatedAssetIndex).
packages/chain-adapters/src/evm/cronos/CronosChainAdapter.ts (1)

18-20: Remove the duplicate isCronosChainAdapter type guard — it's dead code.

The canonical implementation lives in src/lib/utils/cronos.ts with the necessary null/undefined defensive checks, and that's the version consumed throughout the codebase. This one is never called, and the unsafe cast (adapter as ChainAdapter).getType() would throw if adapter is null or undefined.

♻️ Proposed fix
-export const isCronosChainAdapter = (adapter: unknown): adapter is ChainAdapter => {
-  return (adapter as ChainAdapter).getType() === KnownChainIds.CronosMainnet
-}
-
 export class ChainAdapter extends SecondClassEvmAdapter<KnownChainIds.CronosMainnet> {

Based on learnings: "For second-class EVM chain adapters (those extending SecondClassEvmAdapter), the type guard function should only exist in src/lib/utils/[chain].ts with defensive null/undefined and function checks. Do not duplicate the type guard in the adapter file itself, as it is dead code and the utils version is the canonical implementation actually used throughout the codebase." (gomesalexandre, PR #11905)

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

In `@packages/chain-adapters/src/evm/cronos/CronosChainAdapter.ts` around lines 18
- 20, Remove the dead duplicate type guard isCronosChainAdapter from
CronosChainAdapter.ts; instead rely on the canonical implementation in
src/lib/utils/cronos.ts which includes null/undefined and function checks.
Delete the exported isCronosChainAdapter function (the one casting to
ChainAdapter and calling getType() against KnownChainIds.CronosMainnet) so there
is only a single safe type guard used across the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/contracts/second-class-evm-chain.md:
- Line 200: The doc currently tells contributors to add a manual mapping to
manualRelatedAssetIndex but omits which files to modify; update both
generateRelatedAssetIndex.ts and generateChainRelatedAssetIndex.ts to include
the new mapping for the chain native (use the same pattern as the stablecoin
example) by adding an entry in manualRelatedAssetIndex that links the Ethereum
ERC20 identifier (eip155:1/erc20:0x...) to the chain native slip44:60; ensure
you follow the existing stablecoin mapping format and include the exact token
IDs so the per-chain "Popular Asset" filtering works correctly.

In @.claude/plan.md:
- Around line 15-26: The current plan to create synthetic internal txs from
WBERA Withdrawal events in parseTx() (using berachainChainId, WETH_ABI,
WBERA_CONTRACT) can generate false positives; update the fallback so after
detecting this.chainId === berachainChainId && internalTxs.length === 0 you
parse Withdrawal events from the receipt but only convert an event into a
synthetic internal tx when the event.src is not the user's pubkey and either
matches a configured list of known relay/fill contract addresses or passes an
explicit allowlist check; also deduplicate or aggregate multiple Withdrawal
events per tx (e.g., ignore duplicates originating from the same src or sum wad
per src when appropriate) before pushing { from: WBERA_CONTRACT, to: pubkey,
value: wad } so parse() produces Receive transfers with fewer false positives.
- Around line 21-25: The WBERA_CONTRACT constant is incorrect in the plan which
will make the Withdrawal-event fallback in parseTx() never match logs; update
the constant WBERA_CONTRACT to the canonical Berachain mainnet address
0x6969696969696969696969696969696969696969 and in parseTx() (the
berachainChainId conditional after internalTxs Promise.all) filter receipt.logs
for Withdrawal events emitted by that WBERA_CONTRACT, parse pubkey and wad from
the event, and push synthetic internal tx objects shaped like { from:
WBERA_CONTRACT, to: pubkey, value: wad } so the fallback actually produces
internalTxs when none were fetched.

In `@AGENTS.md`:
- Line 31: The "Clean up" step text is ambiguous about pruning remote branches;
update the line that currently reads "Clean up - Clear stashes, prune remote
branches" to explicitly state you should prune stale local remote-tracking
references (e.g., use "git fetch --prune" or "git remote prune origin") and
avoid wording that could be interpreted as deleting branches on the remote (do
not suggest "git push origin --delete <branch>"). Ensure the new phrasing
clarifies the safe intended operation and replaces the existing "prune remote
branches" fragment in AGENTS.md.
- Around line 19-39: Clarify the failure path for quality gates by updating the
MANDATORY WORKFLOW and CRITICAL RULES: state that Step 2 ("Run quality gates —
Tests, linters, builds") must pass before performing Step 4 ("PUSH TO REMOTE"),
and if any gate fails the agent must stop, create an issue/ticket and attach
failure logs, run automatic retries or request human approval (do not perform
"git push"), and only proceed with the push sequence after the issue is resolved
and gates pass; update the wording in the "Step 2" and "CRITICAL RULES" sections
to explicitly prohibit pushing on failed gates and to require recording the
failure (issue, logs) and awaiting remediation or explicit human sign-off.

In `@packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts`:
- Around line 480-482: The fee computation produces "NaN" when
receipt.effectiveGasPrice is undefined; update the calculation in
SecondClassEvmAdapter where `fee` is computed so both operands are wrapped with
`bnOrZero` (i.e., use
bnOrZero(receipt.gasUsed).times(bnOrZero(receipt.effectiveGasPrice)).toFixed(0))
to ensure undefined values become zero and avoid NaN propagating into
`parsedTx.fee`; adjust the `fee` declaration accordingly to use `bnOrZero` on
both `receipt.gasUsed` and `receipt.effectiveGasPrice`.

In `@src/config.ts`:
- Line 69: Update the validator for VITE_CRONOS_NODE_URL to use url() instead of
str(): locate the config schema entry named VITE_CRONOS_NODE_URL and replace its
validator call so it performs URL format validation (use the same url() helper
used by other *_NODE_URL entries) to ensure proper startup validation.

In `@src/state/slices/preferencesSlice/preferencesSlice.ts`:
- Line 43: Add a new environment validator named VITE_FEATURE_CRONOS to the
configuration export (the same config object that holds other VITE_FEATURE_*
keys) by adding VITE_FEATURE_CRONOS: bool({ default: false }) so the feature
flag used by the preferences slice (Cronos) is validated and typed correctly;
update the config export type if necessary so VITE_FEATURE_CRONOS is available
throughout the app.

---

Nitpick comments:
In `@packages/chain-adapters/src/evm/cronos/CronosChainAdapter.ts`:
- Around line 18-20: Remove the dead duplicate type guard isCronosChainAdapter
from CronosChainAdapter.ts; instead rely on the canonical implementation in
src/lib/utils/cronos.ts which includes null/undefined and function checks.
Delete the exported isCronosChainAdapter function (the one casting to
ChainAdapter and calling getType() against KnownChainIds.CronosMainnet) so there
is only a single safe type guard used across the codebase.

In
`@scripts/generateAssetData/generateRelatedAssetIndex/generateChainRelatedAssetIndex.ts`:
- Around line 276-285: Remove the now-unreachable trailing "return" after the
orphan recovery block in generateChainRelatedAssetIndex: the code paths for
group && includes, group && !includes, and !group (the recovery that sets
relatedAssetIndex[existingRelatedAssetKey] = [assetId]) already cover all cases,
so delete the redundant return statement that follows that block (the lone
"return" after handling !group involving group, assetId,
existingRelatedAssetKey, and relatedAssetIndex).

In `@src/plugins/cronos/index.tsx`:
- Around line 22-36: getKnownTokens currently calls fromAssetId(asset.assetId)
twice per asset (once in the .filter predicate and again in .map), causing
redundant work; update getKnownTokens to parse each asset's id once (e.g., use a
single .reduce over assetService.assets or first .map to include parsed =
fromAssetId(asset.assetId) then filter on parsed.chainId/assetNamespace and
return the final object using parsed.assetReference) so you only call
fromAssetId once per asset; target the getKnownTokens function and the use of
fromAssetId, assetService.assets, and the filter/map logic when making this
change.

gomesalexandre and others added 2 commits February 20, 2026 21:19
- wrap effectiveGasPrice in bnOrZero to prevent NaN fee on Cronos
- use url() validator for VITE_CRONOS_NODE_URL in config.ts
- specify both files for native token mapping in contract
- add url() vs str() guidance to contract
- clarify prune wording in AGENTS.md
- add quality gate failure path to AGENTS.md
- remove .claude/plan.md, gitignore claude plans

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NODE_OPTIONS=--max-old-space-size=8192 matches the pattern already used by
dev:web. The monorepo's growing discriminated unions (33 chains × 5 union
types) exceed the default ~4GB heap on GitHub Actions runners.

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.

🤖 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`:
- Around line 480-482: The fee calculation in SecondClassEvmAdapter using
receipt.gasUsed and receipt.effectiveGasPrice can produce NaN for legacy Cronos
receipts where effectiveGasPrice is undefined; update the fee computation in the
block that assigns fee to wrap both operands with bnOrZero (i.e., use
bnOrZero(receipt.gasUsed.toString()) and
bnOrZero(receipt.effectiveGasPrice?.toString())) before multiplying and calling
toFixed(0) so the multiplication never yields NaN and legacy/undefined gas price
values are handled safely.

@gomesalexandre gomesalexandre merged commit 8ba94f7 into develop Feb 21, 2026
6 checks passed
@gomesalexandre gomesalexandre deleted the feat/integrate-cronos-relay branch February 21, 2026 09:28
gomesalexandre added a commit that referenced this pull request Feb 21, 2026
* feat: integrate Mantle (chainId 5000) as second-class EVM chain with 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

* feat: integrate Cronos (chainId 25) as second-class EVM chain with Relay 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

* fix: add mantle coingecko generated adapter and fix test

* fix: add cronos coingecko generated adapter and fix test

* fix: add missing Cronos targetNetwork entry in EvmBaseAdapter

* fix: add Mantle TX status polling via useSendActionSubscriber

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.

* fix: add Cronos TX status polling and relay native asset mapping

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.

* fix: add mantle to coingecko supported chains and zerion

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

* fix: add cronos to coingecko supported chains and zerion

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

* feat: integrate Sonic (eip155:146) as second-class EVM chain with Relay swapper support

* fix: correct Sonic CoinGecko platform ID to sonic-3 and add empty adapter.json

* fix: add native Sonic mapping to adapter.json and fix import sort

* fix: wire Sonic adapter.json into generated index

The Sonic adapter.json (eip155_146) was created but not imported/exported
from the generated index.ts, preventing CoinGecko mapping for Sonic tokens.

* chore: add bead context files (ss-dx5.3 + master ss-dx5)

* chore: add bead context files (ss-dx5.4 + master ss-dx5)

* chore: add bead context files (ss-dx5.7 + master ss-dx5)

* fix: broken merge conflict resolutions for mantle entries

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>

* chore: regenerate mantle assets via generate:chain

77 Mantle assets added with relatedAssetKey cross-chain linking.

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

* fix: resolve merge conflicts and regenerate cronos assets

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

* fix: lint import sort

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

* fix: resolve merge conflicts and regenerate sonic assets

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

* fix: generalize wrapped native detection, fix linea icon, update contract

- Replace Berachain-only WBERA burn detection with generalized
  WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID mapping in SecondClassEvmAdapter
- Add WMNT address for Mantle cross-chain swap native receives
- Fix Linea networkIcon URL (CoinGecko 403 -> relay.link CDN)
- Update second-class-evm-chain contract with wrapped native,
  icon validation, and append-only convention sections

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

* chore: update pr beads context

* fix: add WCRO to wrapped native mapping, regen cronos assets

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

* fix: add wS to wrapped native mapping, regen sonic assets

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

* squash merge feat/integrate-cronos-relay

Emulates squash merge of #11910 into develop.

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

* chore: regen sonic, cronos, linea, mantle assets

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

* chore: remove plan.md, gitignore claude plans

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

* chore: regen sonic, cronos, mantle, linea after develop merge

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

* chore: update pr beads context

* fix: sonic coingecko platform id, icon url, regen 114 assets

CoingeckoAssetPlatform.Sonic was 'sonic-3' (the coin ID) instead of
'sonic' (the platform ID), resulting in zero ERC20 tokens discovered.
Also fix dead icon URL (38051 -> 38108). Update contract with platform
ID verification step.

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

* merge origin/develop (cronos) + add sonic stablecoin related assets

- resolve merge conflicts (keep both cronos + sonic entries)
- add FTM ERC20 → Sonic S native mapping in related asset index
- add Sonic native USDC + bridged USDT to manual stablecoin mappings
- add state migration 296 for sonic
- regenerate chain data with updated mappings

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

---------

Co-authored-by: gomes <17035424+gomesalexandre@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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