Be extremely concise. Sacrifice grammar for concision. Terse responses preferred. No fluff.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Hyperlane Explorer is a Next.js 15 web application for exploring interchain messages on the Hyperlane protocol. It allows users to search, view, and debug cross-chain messages.
- Make the plan extremely concise. Sacrifice grammar for the sake of concision.
- At the end of each plan, give me a list of unresolved questions to answer, if any.
pnpm install # Install dependencies
pnpm run dev # Start dev server (http://localhost:3000)
pnpm run build # Production build
pnpm run typecheck # TypeScript type checking
pnpm run lint # ESLint with Next.js rules
pnpm run test # Run Jest tests
pnpm run prettier # Format code in src/- Zustand store (
src/store.ts) manages global state: chain metadata, MultiProtocolProvider, warp routes - State persists to localStorage with version migrations
- Use
useMultiProvider(),useChainMetadata(),useRegistry()hooks to access state
- GraphQL via urql for querying the Hasura API (
https://explorer4.hasura.app/v1/graphql) - TanStack React Query for caching
- Ethers.js v5 for direct blockchain calls
- PI (Permissionless Interop) chains have separate query paths in
src/features/messages/pi-queries/
Features are self-contained in src/features/:
messages/- Message search, display, and detail cardschains/- Chain metadata and configurationapi/- External API integrationdeliveryStatus/- Message delivery trackingdebugger/- Message inspection utilities
Search filters sync with URL query params via src/utils/queryParams.ts for shareable links.
@hyperlane-xyz/sdk- Core Hyperlane SDK@hyperlane-xyz/registry- Chain and protocol registry (fetched at runtime)@hyperlane-xyz/widgets- Pre-built UI components
NEXT_PUBLIC_REGISTRY_URL- Custom registry URL (optional)NEXT_PUBLIC_REGISTRY_BRANCH- Registry branch (default: 'main')EXPLORER_API_KEYS- JSON object with block explorer API keys
src/consts/config.ts- Runtime configurationsrc/consts/api.ts- API endpointstailwind.config.js- Custom colors, spacing, andxsbreakpoint at 480px
- Single quotes, trailing commas, 100 char line width
- Prettier with import organization and Tailwind class sorting
- Use
clsx()for conditional classNames - No async IIFEs in effects — use
.then().catch()instead ofvoid (async () => { ... })()
We handle ONLY the most important cases. Don't add functionality unless it's small or absolutely necessary.
- Expected issues (external systems, user input): Use explicit error handling, try/catch at boundaries
- Unexpected issues (invalid state, broken invariants): Fail loudly with
throworconsole.error - NEVER add silent fallbacks for unexpected issues - they mask bugs
| Change Location | Backwards-Compat? | Rationale |
|---|---|---|
| Local/uncommitted | No | Iteration speed; no external impact |
| In main unreleased | Preferred | Minimize friction for other developers |
| Released | Required | Prevent breaking downstream integrations |
- Run tests incrementally -
pnpm run testfor Jest tests - Check existing patterns - Search codebase for similar implementations
- Use SDK types - Import from
@hyperlane-xyz/sdk, don't redefine - Zustand for state - Global state in
src/store.ts - Keep changes minimal - Only modify what's necessary; avoid scope creep
- Feature folders - Domain logic in
src/features/, not scattered - Dedupe constants - Check
src/consts/andsrc/types.tsbefore adding new ones - Unit tests for utils - New utility functions need
.test.tsfiles - Query limits - Use
SEARCH_QUERY_LIMITfor searches, larger batches for background ops - Existing utils - Use
formatAmountCompact,shortenAddress,tryGetBlockExplorerAddressUrl - Edge runtime - API routes can't import @hyperlane-xyz/utils; use self-contained code
- Color consistency - Green for success only on destination, blue/neutral elsewhere
Always search the codebase before assuming. Don't hallucinate file paths, function names, or patterns.
grepor search before claiming "X doesn't exist"- Read the actual file before suggesting changes to it
- Check
git logor blame before assuming why code exists - Verify imports exist in
package.jsonbefore using them
If output seems wrong, check:
- Did I read the actual file? Or did I assume its contents?
- Did I search for existing patterns? The codebase likely has examples
- Am I using stale context? Re-read files that may have changed
- Did I verify the error message? Run the command and read actual output