Skip to content

Conversation

@augustocollerone
Copy link

@augustocollerone augustocollerone commented Dec 26, 2025

Summary

This PR delivers part of Milestone 2: Frontend Integration of the CoW Grants Program RFP: CoW Protocol Playground Block Explorer Integration proposal by CoBuilders.

Adds environment variable support to override block explorer URLs in both CoW Swap and CoW Explorer frontends, enabling seamless integration with local block explorers like Otterscan.

demo_after

Milestone 2 Deliverables

Frontend URL Override Support

  • Add REACT_APP_BLOCK_EXPLORER_URL environment variable
  • Override transaction hash links
  • Override address links
  • Override token links
  • Works in both CoW Swap and CoW Explorer frontends

Implementation

  • Modified getExplorerLink function to check env var first
  • Modified getEtherscanUrl/getBlockExplorerUrl functions to check env var first
  • Environment variable documented in .env files
  • All navigation flows work correctly with override

Success Criteria

"One-click navigation from frontends to the local block explorer for all transactions and addresses"

  • Setting REACT_APP_BLOCK_EXPLORER_URL=http://localhost:8003 redirects all explorer links to Otterscan
  • Default behavior unchanged when env var is not set

Changes

Modified Files

File Changes
libs/common-utils/src/getExplorerLink.ts Added BLOCK_EXPLORER_URL_OVERRIDE check before chain default
libs/common-utils/src/legacyAddressUtils.ts Added BLOCK_EXPLORER_URL_OVERRIDE check to getEtherscanUrl
apps/cowswap-frontend/.env Added documentation for new env var
apps/explorer/.env.example Added documentation for new env var

How It Works

    getExplorerLink() / getBlockExplorerUrl()
                      │
                      ▼
    ┌─────────────────────────────────────┐
    │ REACT_APP_BLOCK_EXPLORER_URL set?   │
    └─────────────────────────────────────┘
                      │
          ┌───────────┴───────────┐
          │                       │
         Yes                      No
          │                       │
          ▼                       ▼
    ┌───────────────┐     ┌─────────────────────────────┐
    │ Use override  │     │ Use CHAIN_INFO[chainId]     │
    │ (e.g. :8003)  │     │ (e.g. etherscan.io)         │
    └───────────────┘     └─────────────────────────────┘

Configuration

# In .env or build environment
REACT_APP_BLOCK_EXPLORER_URL=http://localhost:8003

When set, all block explorer links will use this URL:

  • Transaction links: http://localhost:8003/tx/{hash}
  • Address links: http://localhost:8003/address/{address}
  • Token links: http://localhost:8003/token/{address}
  • Block links: http://localhost:8003/block/{number}

Testing

  1. Build with env var set:

    REACT_APP_BLOCK_EXPLORER_URL=http://localhost:8003 yarn build
  2. Verify in browser:

    • Open CoW Swap or Explorer
    • Click any transaction or address link
    • Should navigate to localhost:8003 instead of Etherscan
  3. Verify default behavior:

    • Build without env var
    • Links should still go to chain's default explorer (Etherscan, Gnosisscan, etc.)

Related PRs

Repo PR Description
cow-services #4012 Dockerfile changes to use this feature in Playground

Milestones

Milestone Description Status
M1 Otterscan Integration PR #4000
M2 Frontend Integration This PR (+ PR #4012)
M3 Documentation Pending

Submitted by CoBuilders as part of the CoW Grants Program

Summary by CodeRabbit

  • Documentation

    • Added Block Explorer URL override configuration documentation for local development environments.
  • New Features

    • Enabled custom block explorer integration through environment variable configuration, supporting alternative block explorers.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 26, 2025

@augustocollerone is attempting to deploy a commit to the cow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

Walkthrough

Introduces an optional environment variable BLOCK_EXPLORER_URL_OVERRIDE to allow local development customization of block explorer URLs (e.g., using Otterscan instead of Etherscan). The override is documented in environment files and implemented in utility functions with consistent fallback logic across the codebase.

Changes

Cohort / File(s) Summary
Environment Configuration
apps/cowswap-frontend/.env, apps/explorer/.env.example
Adds documentation for new optional REACT_APP_BLOCK_EXPLORER_URL environment variable with guidance on usage and sample values for local development customization.
Utility Implementation
libs/common-utils/src/getExplorerLink.ts, libs/common-utils/src/legacyAddressUtils.ts
Implements override logic that prioritizes BLOCK_EXPLORER_URL_OVERRIDE environment variable in prefix resolution, with fallbacks to chain-specific explorer URLs and defaults. Includes supporting comments and documentation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • shoom3301
  • alfetopito
  • elena-zh

Poem

🐰 A clever override path we've paved,
For explorers both old and new,
No more Etherscan chains that enslaved,
Otterscan now works right through,
Configuration whispers our way! 🔍

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a REACT_APP_BLOCK_EXPLORER_URL environment variable override feature to common-utils.
Description check ✅ Passed The description is comprehensive and well-structured, covering summary, deliverables, implementation details, testing steps, and related PRs, exceeding basic template requirements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@github-actions
Copy link
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@augustocollerone
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

@augustocollerone augustocollerone marked this pull request as ready for review December 26, 2025 20:47
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
libs/common-utils/src/getExplorerLink.ts (1)

11-21: Well-documented environment variable.

The JSDoc documentation clearly explains the override mechanism and provides a practical example.

Optional: Add trailing slash validation

While the documentation mentions the URL should not include a trailing slash, consider adding runtime validation to prevent potential issues with double slashes in generated URLs:

const BLOCK_EXPLORER_URL_OVERRIDE = process.env.REACT_APP_BLOCK_EXPLORER_URL?.replace(/\/$/, '')

This would automatically strip any trailing slash if present.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a013fb and a8b3175.

📒 Files selected for processing (4)
  • apps/cowswap-frontend/.env
  • apps/explorer/.env.example
  • libs/common-utils/src/getExplorerLink.ts
  • libs/common-utils/src/legacyAddressUtils.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-03T19:23:35.789Z
Learnt from: kernelwhisperer
Repo: cowprotocol/cowswap PR: 6610
File: apps/cowswap-frontend/project.json:38-39
Timestamp: 2025-12-03T19:23:35.789Z
Learning: In the cowswap-frontend project configuration (apps/cowswap-frontend/project.json), the Vite dev server option `"host": true` is set to support Windows + WSL development environments, where binding to all network interfaces is required for the Windows host to access the dev server running in WSL.

Applied to files:

  • apps/cowswap-frontend/.env
🧬 Code graph analysis (2)
libs/common-utils/src/getExplorerLink.ts (2)
libs/common-const/src/chainInfo.ts (1)
  • CHAIN_INFO (74-141)
libs/widget-lib/src/types.ts (1)
  • SupportedChainId (4-4)
libs/common-utils/src/legacyAddressUtils.ts (1)
libs/common-const/src/chainInfo.ts (1)
  • CHAIN_INFO (74-141)
🔇 Additional comments (4)
apps/explorer/.env.example (1)

25-33: LGTM! Clear and helpful documentation.

The documentation clearly explains the block explorer override feature and provides a practical example for local development with Otterscan.

apps/cowswap-frontend/.env (1)

106-116: LGTM! Documentation is consistent across apps.

The documentation matches the format and content in apps/explorer/.env.example, ensuring consistency across the codebase.

libs/common-utils/src/legacyAddressUtils.ts (1)

12-16: LGTM! Clear environment variable declaration.

The constant is well-documented and clearly indicates its purpose for local development.

libs/common-utils/src/getExplorerLink.ts (1)

30-37: LGTM! Correct fallback priority order.

The prefix resolution properly prioritizes the environment override, then the chain's default explorer, and finally the function parameter. This ensures known chains use their correct explorers while still allowing the override for local development.

Comment on lines 77 to +79
function getEtherscanUrl(chainId: SupportedChainId, data: string, type: BlockExplorerLinkType, base?: string): string {
const basePath = base || CHAIN_INFO[chainId]?.explorer
// Allow override via environment variable for local development (e.g., Otterscan)
const basePath = BLOCK_EXPLORER_URL_OVERRIDE || base || CHAIN_INFO[chainId]?.explorer
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix the fallback priority order.

The current fallback order OVERRIDE || base || CHAIN_INFO places the base parameter before the chain's default explorer, which is inconsistent with getExplorerLink.ts (line 37) and likely incorrect.

For known chains with entries in CHAIN_INFO, the chain's default explorer should take precedence over the generic base parameter. The base parameter should serve as a final fallback for unsupported chains, not override known chain explorers.

🔎 Proposed fix to align fallback priority
  // Allow override via environment variable for local development (e.g., Otterscan)
- const basePath = BLOCK_EXPLORER_URL_OVERRIDE || base || CHAIN_INFO[chainId]?.explorer
+ const basePath = BLOCK_EXPLORER_URL_OVERRIDE || CHAIN_INFO[chainId]?.explorer || base

This ensures:

  1. Environment override takes precedence (for local dev)
  2. Chain default is used for known chains
  3. Function parameter serves as final fallback for unknown chains
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function getEtherscanUrl(chainId: SupportedChainId, data: string, type: BlockExplorerLinkType, base?: string): string {
const basePath = base || CHAIN_INFO[chainId]?.explorer
// Allow override via environment variable for local development (e.g., Otterscan)
const basePath = BLOCK_EXPLORER_URL_OVERRIDE || base || CHAIN_INFO[chainId]?.explorer
function getEtherscanUrl(chainId: SupportedChainId, data: string, type: BlockExplorerLinkType, base?: string): string {
// Allow override via environment variable for local development (e.g., Otterscan)
const basePath = BLOCK_EXPLORER_URL_OVERRIDE || CHAIN_INFO[chainId]?.explorer || base
🤖 Prompt for AI Agents
In libs/common-utils/src/legacyAddressUtils.ts around lines 77 to 79, the
fallback order for determining the explorer base is wrong: currently it uses
BLOCK_EXPLORER_URL_OVERRIDE || base || CHAIN_INFO[chainId]?.explorer but should
prefer the chain's configured explorer over the supplied base parameter. Change
the priority so it reads BLOCK_EXPLORER_URL_OVERRIDE ||
CHAIN_INFO[chainId]?.explorer || base, keeping the env override first, the chain
default second, and the function parameter as the final fallback.

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.

1 participant