Skip to content

feat: add etherlink#487

Open
antoncoding wants to merge 2 commits intomasterfrom
feat/etherlink
Open

feat: add etherlink#487
antoncoding wants to merge 2 commits intomasterfrom
feat/etherlink

Conversation

@antoncoding
Copy link
Copy Markdown
Owner

@antoncoding antoncoding commented Apr 1, 2026

Summary by CodeRabbit

  • New Features

    • Full Etherlink support across the app: network entry, RPC config, client integration, allocator, and token set
    • Added Etherlink tokens: USDC, WETH, WBTC, WXTZ, xU3O8, mBASIS, mMEV, mTBILL
    • New .env example entry for an Etherlink public RPC
  • Improvements

    • Safer Morpho app-link handling (conditional external links)
    • Chart/UI color and volume display updated for Etherlink
    • Updated Morpho addresses and genesis date for Etherlink

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
monarch Ready Ready Preview, Comment Apr 16, 2026 2:53pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Etherlink (chain ID 42793) across the app: env var, network enum/config, default/custom RPC clients, Wagmi/AppKit setup, token/address mappings, Morpho integrations, and UI conditional rendering and chart color for Etherlink.

Changes

Cohort / File(s) Summary
Environment
\.env\.local\.example
Added optional NEXT_PUBLIC_ETHERLINK_RPC env var.
Network registry
src/utils/networks.ts
Declared SupportedNetworks.Etherlink, added to ALL_SUPPORTED_NETWORKS, and added full NetworkConfig (viem chain, defaultRPC via NEXT_PUBLIC_ETHERLINK_RPC, explorer, native/wrapped token, block timing).
RPC clients
src/utils/rpc.ts
Imported etherlink and added cached default public client for Etherlink using getDefaultRPC.
Wagmi & AppKit setup
src/store/createWagmiConfig.ts, src/config/appkit.ts
Included etherlink in wagmi chains and transports; created customEtherlink via AppKit RPC wrapper and added it to exported networks.
Token & addresses
src/utils/tokens.ts, src/types/token.ts, src/constants/public-allocator.ts
Added Etherlink token mappings (USDC/WETH/WBTC entries, new WXTZ and Midas tokens), added WETH_BY_CHAIN entry and PUBLIC_ALLOCATOR_ADDRESSES entry for Etherlink.
Morpho integrations & external helpers
src/utils/morpho.ts, src/utils/external.ts
Added Etherlink-specific Morpho addresses, bundler, IRM mapping, genesis date; exported getMorphoNetworkSlug, added supportsMorphoAppLinks, and made market/vault URL helpers fall back to base app when slug undefined.
UI conditional rendering
src/features/autovault/components/vault-identity.tsx, src/features/market-detail/components/market-header.tsx
Gate Morpho links/menu items behind supportsMorphoAppLinks(chainId) so links render only when supported.
UI charts/styles
src/features/admin-v2/components/chain-volume-chart.tsx
Added CHAIN_COLOR_INDEX entry for chain ID 42793 (Etherlink) to select chart/legend color.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant App as App (init)
participant AppKit as AppKit / modal
participant Wagmi as createWagmiConfig
participant RPCUtil as getDefaultRPC / rpc util
App->>AppKit: request networks list
AppKit->>Wagmi: request configured chains
Wagmi->>RPCUtil: resolve default RPC for Etherlink
RPCUtil-->>Wagmi: return RPC URL
Wagmi-->>AppKit: return networks (includes customEtherlink)
AppKit-->>App: initialize modal/adapter with Etherlink

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~23 minutes

Possibly related PRs

  • chore: op configs #484: Adds support for a new chain across env, networks, wagmi/appkit, tokens — very similar integration pattern.
  • feat: arbitrum #158: Adds a new network and updates network/rpc/createWagmiConfig/morpho mappings — overlaps core changes.
  • misc: add tokens #318: Modifies src/utils/tokens.ts to add token entries — directly related to token mapping updates.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add etherlink' directly matches the changeset's main objective: adding Etherlink network support across the codebase.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/etherlink

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.

@coderabbitai coderabbitai bot added the feature request Specific feature ready to be implemented label Apr 1, 2026
Copy link
Copy Markdown

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
src/features/autovault/components/vault-identity.tsx (1)

151-153: ⚠️ Potential issue | 🟡 Minor

Tooltip link not gated by canLinkToMorpho.

Main content correctly skips the link when Morpho app links aren't supported, but the tooltip's actionHref (line 152) still points to vaultHref unconditionally. For Etherlink, this would show a broken external link in the tooltip.

Proposed fix
           actionIcon={<ExternalLinkIcon className="h-4 w-4" />}
-          actionHref={vaultHref}
+          actionHref={canLinkToMorpho ? vaultHref : undefined}
           onActionClick={(e) => e.stopPropagation()}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/autovault/components/vault-identity.tsx` around lines 151 - 153,
The tooltip's actionHref is not gated by the canLinkToMorpho check and still
points to vaultHref, producing a broken external link for Etherlink; update the
tooltip props so actionHref is only set when canLinkToMorpho is true (e.g.,
actionHref={canLinkToMorpho ? vaultHref : undefined}) and ensure any click
handler like onActionClick remains consistent with that gating so the tooltip
shows no external link when linking to Morpho isn't supported.
🧹 Nitpick comments (1)
src/utils/tokens.ts (1)

289-294: WXTZ token missing image.

Consider adding an image for UI consistency, or document that img: undefined is intentional.

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

In `@src/utils/tokens.ts` around lines 289 - 294, The WXTZ token entry in
tokens.ts sets img: undefined which breaks UI consistency; update the token
object for symbol 'WXTZ' by either supplying a valid image path/URL (e.g., point
to the project's token asset or CDN) or explicitly set img to a named
placeholder constant (e.g., TOKEN_PLACEHOLDER) and ensure that constant is
imported/defined for the UI to use; alternatively, if undefined is intentional,
add a short inline comment on the WXTZ object explaining why img is undefined so
maintainers know it's deliberate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils/external.ts`:
- Around line 27-31: Tooltip currently always passes vaultHref into
TooltipContent.actionHref causing an actionable link even when the chain doesn't
support Morpho; update the call site to pass actionHref only when
canLinkToMorpho is true (e.g., actionHref={canLinkToMorpho ? vaultHref :
undefined}) or alternatively remove actionIcon when canLinkToMorpho is false so
TooltipContent won't render the link; locate the TooltipContent usage that
supplies actionHref/actionIcon (where vaultHref is derived from getVaultURL) and
apply the conditional so unsupported chains do not show the link.

In `@src/utils/tokens.ts`:
- Around line 368-373: There are two duplicate token entries for symbol 'xU3O8'
with the same address; remove the incomplete entry (the one missing img and
protocol that appears in the block with symbol: 'xU3O8', img: undefined,
decimals: 18, networks: [...]) so only the complete entry (the one that includes
img and protocol: { name: 'Midas' }) remains; this ensures functions like
findToken()/useTokenPrices.ts (which use Array.find) and statsService.ts (which
reduces/iterates tokens) see the same consistent metadata for 'xU3O8'.

---

Outside diff comments:
In `@src/features/autovault/components/vault-identity.tsx`:
- Around line 151-153: The tooltip's actionHref is not gated by the
canLinkToMorpho check and still points to vaultHref, producing a broken external
link for Etherlink; update the tooltip props so actionHref is only set when
canLinkToMorpho is true (e.g., actionHref={canLinkToMorpho ? vaultHref :
undefined}) and ensure any click handler like onActionClick remains consistent
with that gating so the tooltip shows no external link when linking to Morpho
isn't supported.

---

Nitpick comments:
In `@src/utils/tokens.ts`:
- Around line 289-294: The WXTZ token entry in tokens.ts sets img: undefined
which breaks UI consistency; update the token object for symbol 'WXTZ' by either
supplying a valid image path/URL (e.g., point to the project's token asset or
CDN) or explicitly set img to a named placeholder constant (e.g.,
TOKEN_PLACEHOLDER) and ensure that constant is imported/defined for the UI to
use; alternatively, if undefined is intentional, add a short inline comment on
the WXTZ object explaining why img is undefined so maintainers know it's
deliberate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4d594dd1-9835-41d1-94eb-0c344b33af44

📥 Commits

Reviewing files that changed from the base of the PR and between b1360b4 and e417d0c.

⛔ Files ignored due to path filters (5)
  • src/imgs/chains/etherlink.svg is excluded by !**/*.svg
  • src/imgs/tokens/mbasis.png is excluded by !**/*.png
  • src/imgs/tokens/mmev.svg is excluded by !**/*.svg
  • src/imgs/tokens/mtbill.png is excluded by !**/*.png
  • src/imgs/tokens/xu3o8.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • .env.local.example
  • src/config/appkit.ts
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/features/autovault/components/vault-identity.tsx
  • src/features/market-detail/components/market-header.tsx
  • src/store/createWagmiConfig.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/morpho.ts
  • src/utils/networks.ts
  • src/utils/rpc.ts
  • src/utils/tokens.ts

Comment thread src/utils/external.ts
Comment thread src/utils/tokens.ts Outdated
Copy link
Copy Markdown

@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.

Caution

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

⚠️ Outside diff range comments (1)
src/utils/external.ts (1)

45-66: ⚠️ Potential issue | 🟡 Minor

Add Etherlink case to getChainNameForMerkl or create a guard for unsupported chains.

Etherlink is a supported network but falls through to the default 'ethereum' case, generating incorrect Merkl URLs. Either:

  1. Add Etherlink mapping if Merkl supports it (with correct slug)
  2. Add a guard like supportsMorphoAppLinks (already used at line 11 of this file) to prevent unsupported chains from reaching this function
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/external.ts` around lines 45 - 66, The getChainNameForMerkl
function returns incorrect defaults for Etherlink; either add a specific case
for SupportedNetworks.Etherlink with the correct Merkl slug inside
getChainNameForMerkl, or ensure callers check supportsMorphoAppLinks (the
existing guard used earlier in this file) before calling getChainNameForMerkl so
unsupported chains never hit the switch. Update the switch in
getChainNameForMerkl to include SupportedNetworks.Etherlink => '<correct-slug>'
if Merkl supports it, otherwise add/ensure a pre-check using
supportsMorphoAppLinks to short-circuit and avoid using this function for
unsupported chains.
♻️ Duplicate comments (1)
src/utils/external.ts (1)

21-31: ⚠️ Potential issue | 🟡 Minor

Fallback URL returns generic Morpho homepage.

When network is undefined, these functions return https://app.morpho.org which shows the homepage rather than anything useful. Consider returning an empty string or having callers use supportsMorphoAppLinks() to avoid calling these functions for unsupported chains.

The relevant code snippet shows vault-identity.tsx correctly guards the Link component with canLinkToMorpho, but still passes vaultHref to the tooltip's actionHref. This could render a useless link in the tooltip for Etherlink.

Suggested approach

Either:

  1. Return empty string from these functions when network is undefined, or
  2. Ensure all callers check supportsMorphoAppLinks() before using the URL (including tooltip props)

The second approach is cleaner - callers already have the guard function available.

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

In `@src/utils/external.ts` around lines 21 - 31, The getMarketURL and getVaultURL
functions currently return the generic Morpho homepage when
getMorphoNetworkSlug(chainId) is falsy; change behavior to avoid returning a
misleading homepage by either (A) returning an empty string from getMarketURL
and getVaultURL when network is undefined, or (B) (preferred) ensure all callers
use supportsMorphoAppLinks()/canLinkToMorpho before passing URLs — update
callers like vault-identity.tsx to guard the tooltip's actionHref (e.g.,
vaultHref) so actionHref is only set when supportsMorphoAppLinks() is true; pick
one approach and apply it consistently for both getMarketURL and getVaultURL and
all their call sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/utils/external.ts`:
- Around line 45-66: The getChainNameForMerkl function returns incorrect
defaults for Etherlink; either add a specific case for
SupportedNetworks.Etherlink with the correct Merkl slug inside
getChainNameForMerkl, or ensure callers check supportsMorphoAppLinks (the
existing guard used earlier in this file) before calling getChainNameForMerkl so
unsupported chains never hit the switch. Update the switch in
getChainNameForMerkl to include SupportedNetworks.Etherlink => '<correct-slug>'
if Merkl supports it, otherwise add/ensure a pre-check using
supportsMorphoAppLinks to short-circuit and avoid using this function for
unsupported chains.

---

Duplicate comments:
In `@src/utils/external.ts`:
- Around line 21-31: The getMarketURL and getVaultURL functions currently return
the generic Morpho homepage when getMorphoNetworkSlug(chainId) is falsy; change
behavior to avoid returning a misleading homepage by either (A) returning an
empty string from getMarketURL and getVaultURL when network is undefined, or (B)
(preferred) ensure all callers use supportsMorphoAppLinks()/canLinkToMorpho
before passing URLs — update callers like vault-identity.tsx to guard the
tooltip's actionHref (e.g., vaultHref) so actionHref is only set when
supportsMorphoAppLinks() is true; pick one approach and apply it consistently
for both getMarketURL and getVaultURL and all their call sites.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9c5dcbd6-101f-46c9-8092-2242aafed0f2

📥 Commits

Reviewing files that changed from the base of the PR and between e417d0c and 4081260.

⛔ Files ignored due to path filters (5)
  • src/imgs/chains/etherlink.svg is excluded by !**/*.svg
  • src/imgs/tokens/mbasis.png is excluded by !**/*.png
  • src/imgs/tokens/mmev.svg is excluded by !**/*.svg
  • src/imgs/tokens/mtbill.png is excluded by !**/*.png
  • src/imgs/tokens/xu3o8.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • .env.local.example
  • src/config/appkit.ts
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/features/autovault/components/vault-identity.tsx
  • src/features/market-detail/components/market-header.tsx
  • src/store/createWagmiConfig.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/morpho.ts
  • src/utils/networks.ts
  • src/utils/rpc.ts
  • src/utils/tokens.ts
✅ Files skipped from review due to trivial changes (5)
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/types/token.ts
  • src/features/market-detail/components/market-header.tsx
  • src/utils/morpho.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/store/createWagmiConfig.ts
  • src/utils/rpc.ts
  • src/features/autovault/components/vault-identity.tsx
  • src/utils/tokens.ts

Copy link
Copy Markdown

@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

Caution

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

⚠️ Outside diff range comments (1)
src/utils/external.ts (1)

45-66: ⚠️ Potential issue | 🟡 Minor

Add Etherlink to the Merkl chain mapping.

Merkl supports Etherlink and is actively used for the Apple Farm incentive program there. Add a case for Etherlink (likely SupportedNetworks.Etherlink returning 'etherlink') so requests don't incorrectly fall through to the 'ethereum' default.

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

In `@src/utils/external.ts` around lines 45 - 66, The getChainNameForMerkl
function is missing a branch for SupportedNetworks.Etherlink, causing Etherlink
requests to fall through to the default 'ethereum'; update getChainNameForMerkl
to add a case for SupportedNetworks.Etherlink that returns 'etherlink' so
Etherlink is mapped correctly (modify the switch in getChainNameForMerkl to
include case SupportedNetworks.Etherlink: return 'etherlink';).
♻️ Duplicate comments (1)
src/features/autovault/components/vault-identity.tsx (1)

151-153: ⚠️ Potential issue | 🟡 Minor

Tooltip link still shows for unsupported chains.

actionHref={vaultHref} is passed unconditionally to TooltipContent. For Etherlink, this results in a link to the generic https://app.morpho.org which isn't useful.

Fix: conditionally pass actionHref
           actionIcon={<ExternalLinkIcon className="h-4 w-4" />}
-          actionHref={vaultHref}
+          actionHref={canLinkToMorpho ? vaultHref : undefined}
           onActionClick={(e) => e.stopPropagation()}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/autovault/components/vault-identity.tsx` around lines 151 - 153,
The tooltip link is always shown because actionHref is passed unconditionally;
change the JSX so TooltipContent (or the component receiving actionHref in
vault-identity.tsx) only receives actionHref when the chain is supported—e.g.
replace actionHref={vaultHref} with a conditional prop (pass undefined or omit
the prop when the chain is unsupported), using the existing vaultHref and the
chain-support boolean you have in scope so onActionClick and actionIcon remain
unchanged.
🧹 Nitpick comments (1)
src/utils/tokens.ts (1)

289-294: Missing image for WXTZ.

WXTZ (wrapped native XTZ on Etherlink) has img: undefined. Consider adding an image for UI consistency with other wrapped native tokens.

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

In `@src/utils/tokens.ts` around lines 289 - 294, The token entry for symbol
'WXTZ' has img: undefined; update the WXTZ object in the tokens list to provide
an image reference consistent with other tokens (e.g., a relative asset path or
imported URL), so the UI shows the wrapped XTZ icon; locate the WXTZ object
(symbol: 'WXTZ', networks includes chain: etherlink, address:
'0xc9B53AB2679f573e480d01e0f49e2B5CFB7a3EAb') and replace img: undefined with
the appropriate image reference (or a fallback token image) following the same
pattern used by other token entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils/networks.ts`:
- Around line 176-187: The Etherlink network entry (SupportedNetworks.Etherlink)
calls getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) without an
alchemySubdomain or public fallback, which yields an empty string when the env
var is unset and breaks http() transport in rpc.ts; update the Etherlink object
to call getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC, { alchemySubdomain:
'etherlink-mainnet' }) if Alchemy supports it, or pass a public fallback like {
fallback: 'https://node.mainnet.etherlink.com' } (or similar param your
getRpcUrl supports) so defaultRPC is never an empty string and http() always
receives a valid URL.

---

Outside diff comments:
In `@src/utils/external.ts`:
- Around line 45-66: The getChainNameForMerkl function is missing a branch for
SupportedNetworks.Etherlink, causing Etherlink requests to fall through to the
default 'ethereum'; update getChainNameForMerkl to add a case for
SupportedNetworks.Etherlink that returns 'etherlink' so Etherlink is mapped
correctly (modify the switch in getChainNameForMerkl to include case
SupportedNetworks.Etherlink: return 'etherlink';).

---

Duplicate comments:
In `@src/features/autovault/components/vault-identity.tsx`:
- Around line 151-153: The tooltip link is always shown because actionHref is
passed unconditionally; change the JSX so TooltipContent (or the component
receiving actionHref in vault-identity.tsx) only receives actionHref when the
chain is supported—e.g. replace actionHref={vaultHref} with a conditional prop
(pass undefined or omit the prop when the chain is unsupported), using the
existing vaultHref and the chain-support boolean you have in scope so
onActionClick and actionIcon remain unchanged.

---

Nitpick comments:
In `@src/utils/tokens.ts`:
- Around line 289-294: The token entry for symbol 'WXTZ' has img: undefined;
update the WXTZ object in the tokens list to provide an image reference
consistent with other tokens (e.g., a relative asset path or imported URL), so
the UI shows the wrapped XTZ icon; locate the WXTZ object (symbol: 'WXTZ',
networks includes chain: etherlink, address:
'0xc9B53AB2679f573e480d01e0f49e2B5CFB7a3EAb') and replace img: undefined with
the appropriate image reference (or a fallback token image) following the same
pattern used by other token entries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e1c07139-43c7-4a4b-9068-1066af37b8b7

📥 Commits

Reviewing files that changed from the base of the PR and between 4081260 and 24c820a.

⛔ Files ignored due to path filters (5)
  • src/imgs/chains/etherlink.svg is excluded by !**/*.svg
  • src/imgs/tokens/mbasis.png is excluded by !**/*.png
  • src/imgs/tokens/mmev.svg is excluded by !**/*.svg
  • src/imgs/tokens/mtbill.png is excluded by !**/*.png
  • src/imgs/tokens/xu3o8.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • .env.local.example
  • src/config/appkit.ts
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/features/autovault/components/vault-identity.tsx
  • src/features/market-detail/components/market-header.tsx
  • src/store/createWagmiConfig.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/morpho.ts
  • src/utils/networks.ts
  • src/utils/rpc.ts
  • src/utils/tokens.ts
✅ Files skipped from review due to trivial changes (5)
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/store/createWagmiConfig.ts
  • src/utils/rpc.ts
  • src/constants/public-allocator.ts
  • src/features/market-detail/components/market-header.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/config/appkit.ts
  • src/types/token.ts
  • src/utils/morpho.ts

Comment thread src/utils/networks.ts
Comment on lines +176 to +187
{
network: SupportedNetworks.Etherlink,
chain: etherlinkChain,
logo: require('../imgs/chains/etherlink.svg') as string,
name: 'Etherlink',
defaultRPC: getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC),
blocktime: 4.83,
maxBlockDelay: 10,
explorerUrl: 'https://explorer.etherlink.com',
nativeTokenSymbol: 'XTZ',
wrappedNativeToken: '0xc9B53AB2679f573e480d01e0f49e2B5CFB7a3EAb',
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify default Etherlink public RPC is functional
curl -s -X POST "https://node.mainnet.etherlink.com" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' | jq .

Repository: antoncoding/monarch

Length of output: 118


🏁 Script executed:

# Check getRpcUrl implementation and alchemySubdomain handling
rg "function getRpcUrl|const getRpcUrl" -A 15 src/

Repository: antoncoding/monarch

Length of output: 1023


🏁 Script executed:

# Search for http() transport usage and how empty URLs are handled
rg "http\(" src/utils/rpc.ts -A 3 -B 3

Repository: antoncoding/monarch

Length of output: 1723


🏁 Script executed:

# Look for env var documentation and examples
find . -name ".env*" -o -name "README*" -o -name "docs" -type f | head -20

Repository: antoncoding/monarch

Length of output: 171


🏁 Script executed:

# Check if there are any error handlers or validation for missing RPC URLs
rg "NEXT_PUBLIC.*RPC|getRpcUrl" -B 2 -A 2 src/

Repository: antoncoding/monarch

Length of output: 4177


🏁 Script executed:

# Check .env.local.example for Etherlink RPC documentation
cat -n .env.local.example | grep -i etherlink

Repository: antoncoding/monarch

Length of output: 96


🏁 Script executed:

# Search for error handling or validation around http() or createPublicClient
rg "createPublicClient|http\(" src/utils/rpc.ts -B 3 -A 5 | head -50

Repository: antoncoding/monarch

Length of output: 2083


🏁 Script executed:

# Check if there's any error handling for empty or invalid RPC URLs
rg "RPC|rpcUrl" src/utils/rpc.ts -B 2 -A 2

Repository: antoncoding/monarch

Length of output: 2341


🏁 Script executed:

# Check if Alchemy supports Etherlink subdomain
rg "etherlink" -i src/utils/networks.ts | grep -i alchemy

Repository: antoncoding/monarch

Length of output: 45


🏁 Script executed:

# Verify viem's http() behavior with empty string - check if there's any validation or error handling in documentation or code comments
rg "http\(" -B 5 -A 5 src/ | grep -i "empty\|url\|validate\|error" | head -20

Repository: antoncoding/monarch

Length of output: 428


🏁 Script executed:

# Check getDefaultRPC function to see if it's the same as getRpcUrl
rg "function getDefaultRPC|const getDefaultRPC|export.*getDefaultRPC" -A 10 src/utils/networks.ts

Repository: antoncoding/monarch

Length of output: 436


🏁 Script executed:

# Check if there's initialization validation or error handling that would catch empty RPC URLs
rg "initializeDefaultClients|getClient" src/utils/rpc.ts -B 2 -A 10

Repository: antoncoding/monarch

Length of output: 940


🏁 Script executed:

# Look for any error boundaries or RPC validation in the app initialization
rg "try|catch|Error|throw" src/utils/rpc.ts | head -20

Repository: antoncoding/monarch

Length of output: 174


🏁 Script executed:

# Verify what happens with empty URL in http() - check if viem has inline validation
rg "http\(" -B 2 -A 2 src/utils/rpc.ts

Repository: antoncoding/monarch

Length of output: 1694


🏁 Script executed:

# Check if there's documentation in README about environment variables and Etherlink RPC requirement
grep -i "etherlink\|rpc\|environment" README.md | head -20

Repository: antoncoding/monarch

Length of output: 45


🏁 Script executed:

# Search for any error handling or runtime validation that might catch empty URLs
rg "defaultRPC|getDefaultRPC" src/ -B 3 -A 3 | grep -i "error\|throw\|valid\|empty" | head -20

Repository: antoncoding/monarch

Length of output: 145


🏁 Script executed:

# Check if there's a startup validation function that checks RPC URLs
rg "validate|check|init" src/utils/rpc.ts -i

Repository: antoncoding/monarch

Length of output: 163


🏁 Script executed:

# Check if there's any initialization code that validates RPC URLs on startup
rg "_app|initialization|startup" src/pages -i | head -10

Repository: antoncoding/monarch

Length of output: 112


🏁 Script executed:

# Verify if http() from viem throws on empty URL or just fails silently on request
rg "import.*http|from.*viem" src/utils/rpc.ts -A 2

Repository: antoncoding/monarch

Length of output: 320


🏁 Script executed:

# Check all network configs to compare Etherlink's RPC setup with others
rg "defaultRPC: getRpcUrl" src/utils/networks.ts

Repository: antoncoding/monarch

Length of output: 780


🏁 Script executed:

# Search for how the app uses these clients to see if there's error handling at usage time
rg "getClient|defaultClients" src/ | head -20

Repository: antoncoding/monarch

Length of output: 1614


🏁 Script executed:

# Check if the public Etherlink RPC is documented anywhere in the codebase or comments
rg "node.mainnet.etherlink|etherlink.com" src/

Repository: antoncoding/monarch

Length of output: 135


🏁 Script executed:

# Verify one more time that Etherlink is the only chain without alchemySubdomain
rg "getRpcUrl\(" src/utils/networks.ts | grep -v "alchemySubdomain"

Repository: antoncoding/monarch

Length of output: 780


Etherlink RPC lacks fallback—empty string if env var unset.

Unlike other chains, Etherlink's getRpcUrl() call omits the alchemySubdomain parameter, so when NEXT_PUBLIC_ETHERLINK_RPC is missing, it returns '' (empty string) instead of falling back to Alchemy. This empty string gets passed to http() transport in rpc.ts, causing request failures.

Other networks all have Alchemy subdomains: eth-mainnet, opt-mainnet, base-mainnet, polygon-mainnet, unichain-mainnet, arb-mainnet, hyperliquid-mainnet, monad-mainnet.

Options:

  1. Add alchemySubdomain: 'etherlink-mainnet' if Alchemy supports it, or document as required
  2. Provide public fallback: https://node.mainnet.etherlink.com (verified working, chainId 0xa729)
🧰 Tools
🪛 Betterleaks (1.1.1)

[high] 186-186: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

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

In `@src/utils/networks.ts` around lines 176 - 187, The Etherlink network entry
(SupportedNetworks.Etherlink) calls
getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) without an alchemySubdomain or
public fallback, which yields an empty string when the env var is unset and
breaks http() transport in rpc.ts; update the Etherlink object to call
getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC, { alchemySubdomain:
'etherlink-mainnet' }) if Alchemy supports it, or pass a public fallback like {
fallback: 'https://node.mainnet.etherlink.com' } (or similar param your
getRpcUrl supports) so defaultRPC is never an empty string and http() always
receives a valid URL.

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
src/utils/networks.ts (1)

176-187: ⚠️ Potential issue | 🟠 Major

Missing RPC fallback—returns empty string when env var unset.

This was flagged in a previous review. Without alchemySubdomain and no env var, getRpcUrl returns ''. The http('') transport will fail.

Add a public fallback:

Proposed fix
-    defaultRPC: getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC),
+    defaultRPC: getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) || 'https://node.mainnet.etherlink.com',

Or modify getRpcUrl to accept a third fallback parameter.

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

In `@src/utils/networks.ts` around lines 176 - 187, The Etherlink network entry
(SupportedNetworks.Etherlink / etherlinkChain) uses
getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) which can return an empty
string when the env var is unset; provide a public RPC fallback so defaultRPC is
never empty—either call getRpcUrl with a third fallback argument or replace the
call with a guaranteed public RPC URL string (e.g., a documented Etherlink
public RPC) so the http('') transport cannot fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/utils/networks.ts`:
- Around line 176-187: The Etherlink network entry (SupportedNetworks.Etherlink
/ etherlinkChain) uses getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) which
can return an empty string when the env var is unset; provide a public RPC
fallback so defaultRPC is never empty—either call getRpcUrl with a third
fallback argument or replace the call with a guaranteed public RPC URL string
(e.g., a documented Etherlink public RPC) so the http('') transport cannot fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 15fd8f47-b53e-4ea5-8b8d-1cf360893d4a

📥 Commits

Reviewing files that changed from the base of the PR and between 24c820a and 21f2d07.

⛔ Files ignored due to path filters (5)
  • src/imgs/chains/etherlink.svg is excluded by !**/*.svg
  • src/imgs/tokens/mbasis.png is excluded by !**/*.png
  • src/imgs/tokens/mmev.svg is excluded by !**/*.svg
  • src/imgs/tokens/mtbill.png is excluded by !**/*.png
  • src/imgs/tokens/xu3o8.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • .env.local.example
  • src/config/appkit.ts
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/features/autovault/components/vault-identity.tsx
  • src/features/market-detail/components/market-header.tsx
  • src/store/createWagmiConfig.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/morpho.ts
  • src/utils/networks.ts
  • src/utils/rpc.ts
  • src/utils/tokens.ts
✅ Files skipped from review due to trivial changes (4)
  • src/features/market-detail/components/market-header.tsx
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/types/token.ts
  • src/constants/public-allocator.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/config/appkit.ts
  • src/utils/rpc.ts
  • src/features/autovault/components/vault-identity.tsx
  • src/store/createWagmiConfig.ts
  • src/utils/tokens.ts
  • src/utils/external.ts
  • src/utils/morpho.ts

Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
src/utils/networks.ts (1)

176-187: ⚠️ Potential issue | 🟠 Major

Etherlink defaultRPC can still resolve to an empty string.

getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) has no Alchemy subdomain or explicit fallback, so when the env var is missing, Line 181 can produce '', which breaks downstream RPC transport initialization.

Proposed patch
-    defaultRPC: getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC),
+    defaultRPC: getRpcUrl(
+      process.env.NEXT_PUBLIC_ETHERLINK_RPC || 'https://node.mainnet.etherlink.com'
+    ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/networks.ts` around lines 176 - 187, The Etherlink network entry
can set defaultRPC to an empty string because
getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) has no fallback; update the
network config (the object with network: SupportedNetworks.Etherlink and
property defaultRPC) so defaultRPC can never be empty—either pass a reliable
fallback RPC URL (e.g., a known public/alchemy/infura endpoint or a shared env
var like NEXT_PUBLIC_RPC_FALLBACK) or modify getRpcUrl to accept a fallback
parameter and use that when NEXT_PUBLIC_ETHERLINK_RPC is missing; ensure the fix
touches the defaultRPC assignment for SupportedNetworks.Etherlink and/or the
getRpcUrl signature so downstream RPC initialization never receives an empty
string.
🧹 Nitpick comments (1)
src/features/autovault/components/vault-identity.tsx (1)

96-109: Gate tooltip external action with the same canLinkToMorpho condition.

Right now the main chip link is disabled, but the tooltip still exposes actionHref={vaultHref}. On unsupported chains this can still lead users to a broken/unsupported external route.

Proposed patch
-  const interactiveContent =
-    showLink && canLinkToMorpho ? (
+  const canOpenMorpho = showLink && canLinkToMorpho;
+
+  const interactiveContent =
+    canOpenMorpho ? (
       <Link
         href={vaultHref}
         target="_blank"
         rel="noopener noreferrer"
         className="no-underline"
         onClick={(e) => e.stopPropagation()}
       >
         {baseContent}
       </Link>
     ) : (
       baseContent
     );
-          actionIcon={<ExternalLinkIcon className="h-4 w-4" />}
-          actionHref={vaultHref}
+          actionIcon={canOpenMorpho ? <ExternalLinkIcon className="h-4 w-4" /> : undefined}
+          actionHref={canOpenMorpho ? vaultHref : undefined}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/autovault/components/vault-identity.tsx` around lines 96 - 109,
The tooltip is still exposing actionHref={vaultHref} even when linking is
disabled; update the component in vault-identity.tsx so the tooltip's actionHref
is only set when showLink && canLinkToMorpho (the same guard used for
interactiveContent). Locate the Tooltip (or equivalent) that currently receives
actionHref and change it to pass actionHref={showLink && canLinkToMorpho ?
vaultHref : undefined} (or omit the prop) so unsupported chains don't get a
broken external link; keep references to interactiveContent, baseContent,
canLinkToMorpho, and vaultHref to find the relevant code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/utils/networks.ts`:
- Around line 176-187: The Etherlink network entry can set defaultRPC to an
empty string because getRpcUrl(process.env.NEXT_PUBLIC_ETHERLINK_RPC) has no
fallback; update the network config (the object with network:
SupportedNetworks.Etherlink and property defaultRPC) so defaultRPC can never be
empty—either pass a reliable fallback RPC URL (e.g., a known
public/alchemy/infura endpoint or a shared env var like
NEXT_PUBLIC_RPC_FALLBACK) or modify getRpcUrl to accept a fallback parameter and
use that when NEXT_PUBLIC_ETHERLINK_RPC is missing; ensure the fix touches the
defaultRPC assignment for SupportedNetworks.Etherlink and/or the getRpcUrl
signature so downstream RPC initialization never receives an empty string.

---

Nitpick comments:
In `@src/features/autovault/components/vault-identity.tsx`:
- Around line 96-109: The tooltip is still exposing actionHref={vaultHref} even
when linking is disabled; update the component in vault-identity.tsx so the
tooltip's actionHref is only set when showLink && canLinkToMorpho (the same
guard used for interactiveContent). Locate the Tooltip (or equivalent) that
currently receives actionHref and change it to pass actionHref={showLink &&
canLinkToMorpho ? vaultHref : undefined} (or omit the prop) so unsupported
chains don't get a broken external link; keep references to interactiveContent,
baseContent, canLinkToMorpho, and vaultHref to find the relevant code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5217e615-0e51-44a5-909e-3b1e58ceca55

📥 Commits

Reviewing files that changed from the base of the PR and between 21f2d07 and 8fa6369.

⛔ Files ignored due to path filters (5)
  • src/imgs/chains/etherlink.svg is excluded by !**/*.svg
  • src/imgs/tokens/mbasis.png is excluded by !**/*.png
  • src/imgs/tokens/mmev.svg is excluded by !**/*.svg
  • src/imgs/tokens/mtbill.png is excluded by !**/*.png
  • src/imgs/tokens/xu3o8.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • .env.local.example
  • src/config/appkit.ts
  • src/constants/public-allocator.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/features/autovault/components/vault-identity.tsx
  • src/features/market-detail/components/market-header.tsx
  • src/store/createWagmiConfig.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/morpho.ts
  • src/utils/networks.ts
  • src/utils/rpc.ts
  • src/utils/tokens.ts
✅ Files skipped from review due to trivial changes (3)
  • src/features/market-detail/components/market-header.tsx
  • src/constants/public-allocator.ts
  • src/utils/tokens.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/store/createWagmiConfig.ts
  • src/features/admin-v2/components/chain-volume-chart.tsx
  • src/config/appkit.ts
  • src/types/token.ts
  • src/utils/external.ts
  • src/utils/rpc.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Specific feature ready to be implemented

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant