Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
011af5a
feat: add real-time validator signature status display
nambrot Jan 15, 2026
167e6ed
style: fix prettier formatting
nambrot Jan 15, 2026
3602d9e
feat: add warp route visualization card for message details
nambrot Jan 23, 2026
c83c7ec
feat: add ICA message decoding and visualization
yorhodes Jan 28, 2026
9b29e59
refactor: clean up message details UI
yorhodes Jan 28, 2026
5483da2
fix: address PR review comments and fix CI
nambrot Jan 29, 2026
1411bdb
feat: add transaction page to view all messages in a tx
yorhodes Jan 28, 2026
4adb5e0
refactor: flatten nested if for cleaner rendering logic
nambrot Jan 29, 2026
8aee94d
fix: address PR review comments for tx page
yorhodes Jan 29, 2026
b54ebb9
fix: address PR review comments and add ICA debugger enhancements
yorhodes Jan 29, 2026
e5e15ba
Merge feat/ica-decoding into feat/tx-page
yorhodes Jan 29, 2026
f5fa4d3
fix: constrain tx page width for better layout
yorhodes Jan 29, 2026
a9eae49
refactor: address remaining PR review comments
nambrot Jan 29, 2026
16b44ab
fix: revert to synchronous explorer URL generation to avoid 429s
nambrot Jan 29, 2026
c6cc770
fix: address additional PR review comments
nambrot Jan 29, 2026
241bc22
fix: prevent automatic refetches in useWarpRouteVisualization to avoi…
nambrot Jan 29, 2026
00df585
refactor: use TokenType from SDK and improve explorer URL handling
nambrot Feb 3, 2026
2c8cd25
Merge branch 'main' into nam/warp-route-visualization
nambrot Feb 3, 2026
123108e
refactor: use tryGetBlockExplorerAddressUrl directly
nambrot Feb 3, 2026
ee0a681
fix: use displayName in expanded view nodes
nambrot Feb 3, 2026
9061124
fix: address CodeRabbit review comments
nambrot Feb 3, 2026
2e6d04a
style: address CodeRabbit nitpick suggestions
nambrot Feb 3, 2026
e6d52ac
fix: log registry fetch failures with error context
nambrot Feb 3, 2026
f2e1fcf
fix: defer RPC calls until warp route visualization is expanded
nambrot Feb 3, 2026
6c1cd05
fix: stabilize query keys to prevent excessive RPC refetching
nambrot Feb 3, 2026
401f98e
fix: eliminate RPC flood by using registry data for token types
nambrot Feb 3, 2026
d602009
style: fix prettier formatting
nambrot Feb 4, 2026
41a34aa
refactor: simplify warp route visualization to basic view only
nambrot Feb 4, 2026
4154bce
merge: resolve conflicts with main
nambrot Feb 4, 2026
dcfa89f
fix: address PR review feedback
nambrot Feb 5, 2026
38f2eb3
fix: use explicit boolean check for chainBalance conditionals
nambrot Feb 5, 2026
5e2d912
fix: guard transfer label pill against undefined values
nambrot Feb 6, 2026
81c440a
Merge branch 'main' into nam/warp-route-visualization
nambrot Feb 6, 2026
c2cc210
fix: address CodeRabbit review comments
nambrot Feb 7, 2026
f51f454
Merge remote-tracking branch 'origin/main' into refactor/message-deta…
paulbalaji Feb 7, 2026
bf647b1
fix: show full token icons instead of clipping to circle
paulbalaji Feb 7, 2026
fce7495
feat: update color palette for purple/pink rebrand
paulbalaji Jan 3, 2026
d8723d5
feat: update typography to PP Valve and PP Fraktion Mono
paulbalaji Jan 3, 2026
4606988
feat: update logos and favicon for purple rebrand
paulbalaji Jan 3, 2026
3d9b189
feat: apply rebrand styling to UI components
paulbalaji Jan 3, 2026
d2c1b8c
feat: update OG images with purple brand theme
paulbalaji Jan 3, 2026
d2448bb
fix: use purple for delivered checkmark icon
paulbalaji Jan 3, 2026
d240426
fix: use purple for envelope and fuel pump icons
paulbalaji Jan 3, 2026
6517ef3
refine: polish rebrand styling and remove legacy fonts
paulbalaji Jan 4, 2026
33edf27
refine: favicon scaling, OG image footer, and filter button styling
paulbalaji Jan 4, 2026
8bdf60b
prettier
paulbalaji Jan 4, 2026
25efaea
refine: use accent-600 for buttons and primary-500 for nav highlights
paulbalaji Feb 7, 2026
8da19b8
feat: add AWS S3 font downloader script
paulbalaji Jan 13, 2026
b282332
fix: update lockfile
paulbalaji Jan 13, 2026
f686a69
refine: unify purple color scheme and boxy styling across UI
paulbalaji Jan 5, 2026
8059a67
fix: override widget white backgrounds to use cream (#f8f8ff)
paulbalaji Jan 5, 2026
b93b291
refine: add darker backdrop fade for chain picker modal
paulbalaji Jan 5, 2026
42a3711
fix: modal backdrop z-index and gray color matching
paulbalaji Jan 5, 2026
0bca825
fix: ensure modal panel appears above backdrop
paulbalaji Jan 5, 2026
fbc07ca
refine: match widget hover states and gray backgrounds
paulbalaji Jan 5, 2026
19e5414
refine: update filter buttons and checkmarks to pink accent-600
paulbalaji Jan 5, 2026
026303d
revert: checkmarks back to purple (primary-500)
paulbalaji Jan 5, 2026
35361b4
feat: use more muted styling for panel headings
paulbalaji Jan 13, 2026
725642a
fix: ensure consistent header height across pages
paulbalaji Jan 13, 2026
0df11ed
refactor: use Color enum instead of hardcoded hex values
paulbalaji Feb 7, 2026
ac44ce2
fix: restore default truncation in KeyValueRow when displayWidth is u…
paulbalaji Feb 7, 2026
374d44a
fix: use darker purple (#4c1d95) for timeline tracker stages
paulbalaji Feb 7, 2026
8a7caf1
Merge origin/nam/validator-signature-status into pb/offsite-swap
paulbalaji Feb 10, 2026
3964533
Merge remote-tracking branch 'origin/nam/warp-route-visualization' in…
paulbalaji Feb 10, 2026
bee94be
Merge origin/feat/ica-decoding into pb/offsite-swap
paulbalaji Feb 10, 2026
c6db009
Merge origin/feat/tx-page into pb/offsite-swap
paulbalaji Feb 10, 2026
37471b4
fix: resolve type errors from merge (unused imports)
paulbalaji Feb 10, 2026
dd84480
fix: regenerate lockfile to match overrides
paulbalaji Feb 10, 2026
02e6277
fix: align merged PR styling with rebrand colors
paulbalaji Feb 10, 2026
3a0f940
style: fix prettier formatting
paulbalaji Feb 10, 2026
02e1c72
fix: wrap HubIcon SVG import in Image component for SectionCard
paulbalaji Feb 10, 2026
5a6df5c
fix: remove icon from Warp Route Overview section header
paulbalaji Feb 10, 2026
00a81c1
fix: expand warp route overview by default
paulbalaji Feb 10, 2026
9d1346a
fix: use SVG icons instead of emoji, lighten timeline to primary-600
paulbalaji Feb 10, 2026
1b1cce5
fix: increase border radius and spacing for less blocky UI
paulbalaji Feb 10, 2026
2befb27
fix: remove duplicate grid in ContentDetailsCard and revert over-spacing
paulbalaji Feb 10, 2026
e2ec167
perf(build): enable parallel build flags for faster builds
paulbalaji Feb 11, 2026
5353ac0
merge origin/main into pb/offsite-swap
paulbalaji Feb 12, 2026
08bcb7d
fix: use on-brand colors for ICA status cards
paulbalaji Feb 12, 2026
0e8315c
fix: use primary purple for ICA pending states instead of blue
paulbalaji Feb 12, 2026
ed18d48
feat: decode common calldata in ICA call cards
paulbalaji Feb 12, 2026
c0cec33
feat: decode Uniswap swaps with token symbols in ICA calls
paulbalaji Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# AWS S3 Font Storage (server-side only, used by prebuild script)
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_S3_BUCKET=your_bucket_name
AWS_REGION=us-east-1
Binary file added .yarn/install-state.gz
Binary file not shown.
4 changes: 4 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,14 @@ const nextConfig = {
layers: true,
};


return config;
},

experimental: {
webpackBuildWorker: true,
parallelServerCompiles: true,
parallelServerBuildTraces: true,
optimizePackageImports: [
'@hyperlane-xyz/registry',
'@hyperlane-xyz/sdk',
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"zustand": "^4.5.5"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.967.0",
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^9.39.1",
"@tanstack/eslint-plugin-query": "^5.28.6",
Expand Down Expand Up @@ -75,6 +76,8 @@
},
"scripts": {
"clean": "rm -rf dist cache .next",
"prebuild": "node scripts/fetch-fonts.mjs",
"fetch-fonts": "node --env-file=.env.local scripts/fetch-fonts.mjs",
"dev": "next dev",
"build": "next build",
"typecheck": "tsc",
Expand All @@ -91,7 +94,8 @@
"cipher-base": "1.0.5",
"elliptic": "6.6.1",
"pbkdf2": "3.1.3",
"form-data": "4.0.4"
"form-data": "4.0.4",
"@hyperlane-xyz/sdk": "21.1.0-preview.9c72f6fb2deb13238aa68a4a83bff7a7156047e6"
},
"onlyBuiltDependencies": []
}
Expand Down
1,701 changes: 1,000 additions & 701 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Binary file modified public/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/fonts/NeueHaasDisplayBold.woff
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayBold.woff2
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayLight.woff
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayLight.woff2
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayMedium.ttf
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayMedium.woff
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayMedium.woff2
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayRoman.woff
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayRoman.woff2
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayThin.woff
Binary file not shown.
Binary file removed public/fonts/NeueHaasDisplayThin.woff2
Binary file not shown.
Binary file removed public/fonts/SpaceGrotesk-Medium.ttf
Binary file not shown.
4 changes: 2 additions & 2 deletions public/images/arrow-right-gradient.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 9 additions & 9 deletions public/images/hyperlane-logo-color.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/mstile-150x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 87 additions & 0 deletions scripts/fetch-fonts.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { createWriteStream, existsSync, mkdirSync } from 'fs';
import { dirname, join } from 'path';
import { Readable } from 'stream';
import { pipeline } from 'stream/promises';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const FONTS_DIR = join(__dirname, '..', 'public', 'fonts');

// Font files to download from S3
const FONTS = [
// Variable fonts for CSS (browser rendering)
'PPValve-PlainVariable.woff2',
'PPFraktionMono-Variable.woff2',
// TTF fonts for OG image generation (Satori requires TTF)
'PPValve-PlainMedium.ttf',
'PPFraktionMono-Regular.ttf',
];

async function fetchFonts() {
const { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_S3_BUCKET, AWS_REGION } = process.env;

// Gracefully skip if environment variables are not configured
if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_S3_BUCKET) {
console.warn('AWS environment variables not configured - skipping font download');
console.warn(
'To enable font fetching, set: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_S3_BUCKET',
);
return;
}

const s3 = new S3Client({
region: AWS_REGION || 'us-east-1',
credentials: {
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
},
});

// Ensure fonts directory exists
if (!existsSync(FONTS_DIR)) {
mkdirSync(FONTS_DIR, { recursive: true });
console.log(`Created directory: ${FONTS_DIR}`);
}

const results = { success: [], failed: [] };

// Download each font, continuing on failure
for (const fontFile of FONTS) {
const outputPath = join(FONTS_DIR, fontFile);

try {
console.log(`Downloading ${fontFile}...`);

const command = new GetObjectCommand({
Bucket: AWS_S3_BUCKET,
Key: fontFile,
});

const response = await s3.send(command);
const writeStream = createWriteStream(outputPath);

await pipeline(Readable.fromWeb(response.Body.transformToWebStream()), writeStream);

console.log(`Downloaded ${fontFile}`);
results.success.push(fontFile);
} catch (error) {
console.warn(`Failed to download ${fontFile}: ${error.message}`);
results.failed.push(fontFile);
}
}

// Summary
console.log(
`\nFont download complete: ${results.success.length} succeeded, ${results.failed.length} failed`,
);

if (results.failed.length > 0) {
console.warn('Failed fonts:', results.failed.join(', '));
}
}

fetchFonts().catch((error) => {
console.warn('Font fetch script encountered an error:', error.message);
// Exit gracefully - don't fail the build
});
12 changes: 4 additions & 8 deletions src/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@ export function AppLayout({ pathName, children }: PropsWithChildren<Props>) {
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{`Hyperlane Explorer | ${getHeadTitle(pathName)}`}</title>
</Head>
<div
style={styles.container}
className="min-w-screen relative flex h-full min-h-screen w-full flex-col justify-between bg-blue-500"
>
{/* <InfoBanner /> */}
<div className="min-w-screen relative flex h-full min-h-screen w-full flex-col justify-between bg-brand-gradient">
<div className="pointer-events-none fixed inset-0 z-0" style={styles.starOverlay} />
<Header pathName={pathName} />
<div className="mx-auto max-w-5xl grow">
<div className="relative z-10 mx-auto max-w-5xl grow">
<main style={styles.main} className="relative min-h-full pt-3">
{children}
</main>
Expand All @@ -42,10 +39,9 @@ function getHeadTitle(pathName: string) {
}

const styles = {
container: {
starOverlay: {
backgroundImage: 'url(/images/background.svg)',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
},
main: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/buttons/RadioButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function RadioButtons({ options, selected, onChange, label }: Props) {
key={o.value}
value={o.value}
className={({ checked }) =>
`${checked ? 'bg-blue-500 hover:bg-blue-400' : 'bg-white hover:bg-gray-100'} relative flex cursor-pointer px-2 py-1.5 outline-none`
`${checked ? 'bg-primary-500 hover:bg-primary-400' : 'bg-white hover:bg-gray-100'} relative flex cursor-pointer px-2 py-1.5 outline-none`
}
>
{({ checked }) => (
Expand Down
20 changes: 10 additions & 10 deletions src/components/buttons/SolidButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PropsWithChildren, ReactElement } from 'react';

interface ButtonProps {
color?: 'white' | 'blue' | 'green' | 'red' | 'pink'; // defaults to blue
color?: 'white' | 'primary' | 'green' | 'red' | 'accent';
type?: 'submit' | 'reset' | 'button';
onClick?: () => void;
classes?: string;
Expand All @@ -24,18 +24,18 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
title,
passThruProps,
} = props;
const color = _color ?? 'blue';
const color = _color ?? 'primary';

const base = 'flex items-center justify-center rounded-full transition-all duration-500';
let baseColors, onHover, onActive;
if (color === 'blue') {
baseColors = 'bg-blue-500 text-white';
onHover = 'hover:bg-blue-600';
onActive = 'active:bg-blue-700';
} else if (color === 'pink') {
baseColors = 'bg-pink-500 text-white';
onHover = 'hover:bg-pink-600';
onActive = 'active:bg-pink-700';
if (color === 'primary') {
baseColors = 'bg-primary-600 text-white';
onHover = 'hover:bg-primary-700';
onActive = 'active:bg-primary-800';
} else if (color === 'accent') {
baseColors = 'bg-accent-700 text-white';
onHover = 'hover:bg-accent-800';
onActive = 'active:bg-accent-900';
} else if (color === 'green') {
baseColors = 'bg-green-500 text-white';
onHover = 'hover:bg-green-600';
Expand Down
28 changes: 28 additions & 0 deletions src/components/icons/CheckmarkIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { memo } from 'react';

import { Color } from '../../styles/Color';

interface Props {
width?: number;
height?: number;
color?: string;
className?: string;
}

function _CheckmarkIcon({ width = 16, height = 16, color = Color.primary, className }: Props) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
width={width}
height={height}
className={className}
fill={color}
>
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z" />
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z" />
</svg>
);
}

export const CheckmarkIcon = memo(_CheckmarkIcon);
Loading