feat: integrate Hemi (chainId: 43111) via Relay#11931
feat: integrate Hemi (chainId: 43111) via Relay#11931gomesalexandre merged 14 commits intodevelopfrom
Conversation
📝 WalkthroughWalkthroughAdds Hemi mainnet (eip155:43111) as a second-class EVM chain across the codebase: environment vars, CAIP/constants, chain adapter, viem/ethers clients, Coingecko mappings, asset generation, wallet capability flags, feature gating, plugin registration, and minor tests/data updates. Changes
Sequence Diagram(s)sequenceDiagram
participant App as App (UI)
participant Plugin as PluginRegistry
participant AssetSvc as AssetService
participant Adapter as HemiChainAdapter
participant RPC as Hemi RPC (VITE_HEMI_NODE_URL)
participant Wallet as Wallet (HDWallet)
App->>Plugin: register plugins on startup (feature flag read)
Plugin->>Adapter: initialize HemiChainAdapter (rpcUrl from config)
App->>AssetSvc: request assets (includes hemi if enabled)
AssetSvc->>Adapter: getKnownTokens() (adapter-provided token list)
App->>Wallet: wallet capability check (supportsHemi)
App->>Adapter: send tx / query tx status
Adapter->>RPC: JSON-RPC call (getReceipt)
RPC-->>Adapter: receipt/status
Adapter-->>App: normalized tx status
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/lib/utils/hemi.ts (1)
39-41: Prefer structured logger overconsole.error.The coding guideline requires structured logging with relevant context. Other utility modules in this codebase use a logger instance (e.g.,
moduleLogger) rather than rawconsole.error.♻️ Proposed fix
+import { logger } from '@/lib/logger' + +const moduleLogger = logger.child({ namespace: ['lib', 'utils', 'hemi'] }) + // inside catch block: - console.error('[Hemi] Error getting transaction status:', error) + moduleLogger.error({ error }, '[Hemi] Error getting transaction status')As per coding guidelines: "ALWAYS log errors for debugging using structured logging with relevant context and error metadata."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/utils/hemi.ts` around lines 39 - 41, Replace the raw console.error in the catch block of the get transaction status flow with the moduleLogger structured logger: call moduleLogger.error and include a descriptive message, the transaction id/context if available, and the caught error object/metadata so the log is structured and searchable; keep the existing return TxStatus.Unknown and ensure moduleLogger is imported or available in the hemi.ts file before using it..env (1)
159-161:VITE_HEMI_NODE_URLkey ordering — should precedeVITE_KATANA_NODE_URL.
dotenv-linterreports thatVITE_HEMI_NODE_URL(H) should appear beforeVITE_KATANA_NODE_URL(K) to maintain alphabetical ordering. Similarly,VITE_FEATURE_HEMI(line 308) should appear beforeVITE_FEATURE_HYPEREVMsinceHEprecedesHY.♻️ Proposed reordering
In the nodes section, move
VITE_HEMI_NODE_URLbeforeVITE_KATANA_NODE_URL:VITE_MEGAETH_NODE_URL=https://mainnet.megaeth.com/rpc +VITE_HEMI_NODE_URL=https://rpc.hemi.network/rpc VITE_KATANA_NODE_URL=https://rpc.katana.network -VITE_HEMI_NODE_URL=https://rpc.hemi.network/rpcIn the feature flags section, move
VITE_FEATURE_HEMIbeforeVITE_FEATURE_HYPEREVM:+VITE_FEATURE_HEMI=false VITE_FEATURE_HYPEREVM=true VITE_FEATURE_MEGAETH=false -VITE_FEATURE_HEMI=false🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env around lines 159 - 161, Reorder the environment keys to satisfy alphabetical ordering: move the VITE_HEMI_NODE_URL entry so it appears before VITE_KATANA_NODE_URL in the nodes block, and move VITE_FEATURE_HEMI so it appears before VITE_FEATURE_HYPEREVM in the feature flags block; ensure there are no duplicate keys and preserve existing values and spacing when making these swaps.src/plugins/hemi/index.tsx (1)
22-36:fromAssetIdcalled twice per asset — optional combine intoreduce.
fromAssetId(asset.assetId)is invoked once in thefilterand again in themapfor every asset that passes. SinceassetReferenceis available from the first call, a singlereduceeliminates the redundant parse.♻️ Proposed refactor
-const getKnownTokens = () => { - const assetService = getAssetService() - return assetService.assets - .filter(asset => { - const { chainId, assetNamespace } = fromAssetId(asset.assetId) - return chainId === hemiChainId && assetNamespace === 'erc20' - }) - .map(asset => ({ - assetId: asset.assetId, - contractAddress: fromAssetId(asset.assetId).assetReference, - symbol: asset.symbol, - name: asset.name, - precision: asset.precision, - })) -} +const getKnownTokens = () => { + const assetService = getAssetService() + return assetService.assets.reduce< + { assetId: string; contractAddress: string; symbol: string; name: string; precision: number }[] + >((acc, asset) => { + const { chainId, assetNamespace, assetReference } = fromAssetId(asset.assetId) + if (chainId === hemiChainId && 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/hemi/index.tsx` around lines 22 - 36, getKnownTokens currently calls fromAssetId twice per asset (once in filter and again in map); refactor getKnownTokens to call fromAssetId only once per asset by iterating assetService.assets with a single pass (e.g., reduce or a single map+filter) that parses const parsed = fromAssetId(asset.assetId), checks parsed.chainId === hemiChainId && parsed.assetNamespace === 'erc20', and if so pushes/returns the object using parsed.assetReference for contractAddress and the asset fields (assetId, symbol, name, precision); update getKnownTokens to use this single-pass approach to eliminate the redundant fromAssetId calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.env:
- Around line 159-161: Reorder the environment keys to satisfy alphabetical
ordering: move the VITE_HEMI_NODE_URL entry so it appears before
VITE_KATANA_NODE_URL in the nodes block, and move VITE_FEATURE_HEMI so it
appears before VITE_FEATURE_HYPEREVM in the feature flags block; ensure there
are no duplicate keys and preserve existing values and spacing when making these
swaps.
In `@src/lib/utils/hemi.ts`:
- Around line 39-41: Replace the raw console.error in the catch block of the get
transaction status flow with the moduleLogger structured logger: call
moduleLogger.error and include a descriptive message, the transaction id/context
if available, and the caught error object/metadata so the log is structured and
searchable; keep the existing return TxStatus.Unknown and ensure moduleLogger is
imported or available in the hemi.ts file before using it.
In `@src/plugins/hemi/index.tsx`:
- Around line 22-36: getKnownTokens currently calls fromAssetId twice per asset
(once in filter and again in map); refactor getKnownTokens to call fromAssetId
only once per asset by iterating assetService.assets with a single pass (e.g.,
reduce or a single map+filter) that parses const parsed =
fromAssetId(asset.assetId), checks parsed.chainId === hemiChainId &&
parsed.assetNamespace === 'erc20', and if so pushes/returns the object using
parsed.assetReference for contractAddress and the asset fields (assetId, symbol,
name, precision); update getKnownTokens to use this single-pass approach to
eliminate the redundant fromAssetId calls.
- Fix 8 missing closing braces/parens across merge conflict resolutions - Fix ethOnBob/ethOnHemi ordering in coingecko index test - Add hemiAssetId to generateChainRelatedAssetIndex ETH array - Add Hemi WETH address to WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID - Add VITE_HEMI_NODE_URL and VITE_FEATURE_HEMI to vite-env.d.ts - Fix market service test duplicate assertions - Deduplicate generateRelatedAssetIndex entries Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add eip155:43111/slip44:60 (Hemi ETH) to generatedAssetData.json - Add Hemi to ETH relatedAssetIndex group - Regenerate compressed files and manifest hashes Co-Authored-By: Claude Opus 4.6 <[email protected]>
…i-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/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/portfolioSlice/utils/index.ts # src/state/slices/preferencesSlice/preferencesSlice.ts # src/test/mocks/store.ts # src/vite-env.d.ts
Co-Authored-By: Claude Opus 4.6 <[email protected]>
cbbe520 to
4fd1018
Compare
Co-Authored-By: Claude Opus 4.6 <[email protected]>
yarn generate:chain eip155:43111 - picks up WETH, WBTC, LINK, USDC.E, USDT, HEMI, and various BTC variants via Zerion discovery. Co-Authored-By: Claude Opus 4.6 <[email protected]>
The Soneium PR collapsed per-chain EVM handlers into a generic default case using SecondClassEvmAdapter.getTransactionStatus(). Merge brought the old imports back - nuke them. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
gomesalexandre
left a comment
There was a problem hiding this comment.
Stamping for the sake of progression since it's under flag. But noting I can't seem to get fills, or they must be v. long, probably a liquidity issue on solvers' side
https://jam.dev/c/4bade081-b56a-49bc-8441-f20a52f6c554
Bob (60808) comes before Hemi (43111) in adapter registration order. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
🧹 Nitpick comments (3)
.env (2)
165-165:dotenv-linterflagsVITE_HEMI_NODE_URLas out of order.The linter expects
VITE_HEMI_NODE_URLbeforeVITE_INK_NODE_URL(H < I). While the surrounding nodes block is already not strictly alphabetical, you may want to align it at some point.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env at line 165, The .env entry VITE_HEMI_NODE_URL is out of alphabetical order according to dotenv-linter; move the VITE_HEMI_NODE_URL line so it appears before VITE_INK_NODE_URL (i.e., place the VITE_HEMI_NODE_URL key in the correct alphabetical position among the node URL variables) to satisfy the linter and keep the nodes block consistently ordered.
325-325:VITE_FEATURE_HEMI=false— value and placement look correct.Setting the production default to
falseis consistent with other second-class chains (Mantle, Ink, Cronos, etc.). Thedotenv-linteralso flags this key as out of order (should precedeVITE_FEATURE_HYPEREVM), but the surrounding block is already unordered.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env at line 325, The VITE_FEATURE_HEMI environment key is correctly set to false and placed as a production default; leave VITE_FEATURE_HEMI=false unchanged, but if you want to satisfy dotenv-linter reorder it to appear before VITE_FEATURE_HYPEREVM (i.e., swap the two entries) while preserving the false value..env.development (1)
64-64: Same RPC URL as base.env— consistent with other public-RPC chains.The
dotenv-linteralso flags the ordering here (H < K), matching the same pre-existing inconsistency in.env.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env.development at line 64, The VITE_HEMI_NODE_URL entry in .env.development duplicates the same value from the base .env and breaks dotenv-linter alphabetical ordering; either remove the redundant VITE_HEMI_NODE_URL from .env.development so the base value is used, or reorder the keys in .env.development to place VITE_HEMI_NODE_URL in the correct alphabetical position (and ensure dotenv-linter passes), referencing the VITE_HEMI_NODE_URL variable to locate the line to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.env:
- Line 165: The .env entry VITE_HEMI_NODE_URL is out of alphabetical order
according to dotenv-linter; move the VITE_HEMI_NODE_URL line so it appears
before VITE_INK_NODE_URL (i.e., place the VITE_HEMI_NODE_URL key in the correct
alphabetical position among the node URL variables) to satisfy the linter and
keep the nodes block consistently ordered.
- Line 325: The VITE_FEATURE_HEMI environment key is correctly set to false and
placed as a production default; leave VITE_FEATURE_HEMI=false unchanged, but if
you want to satisfy dotenv-linter reorder it to appear before
VITE_FEATURE_HYPEREVM (i.e., swap the two entries) while preserving the false
value.
In @.env.development:
- Line 64: The VITE_HEMI_NODE_URL entry in .env.development duplicates the same
value from the base .env and breaks dotenv-linter alphabetical ordering; either
remove the redundant VITE_HEMI_NODE_URL from .env.development so the base value
is used, or reorder the keys in .env.development to place VITE_HEMI_NODE_URL in
the correct alphabetical position (and ensure dotenv-linter passes), referencing
the VITE_HEMI_NODE_URL variable to locate the line to change.
Part of #11902. Adds Hemi as second-class EVM chain behind feature flag. ETH-native, OP Stack L2.
This is PR 8 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:
Summary by CodeRabbit
New Features
Chores
Tests