Conversation
chore: bump version from 1.2.2-alpha to 1.2.3-alpha
Add source field support from explorer-metadata PR #11 to display a "Verified by Kleros" tag next to addresses tagged by the Kleros curated list.
- Add KlerosService with GraphQL query against Kleros ATQ subgraph - Add useKlerosTag hook with fallback to metadata CDN - Show Public Name Tag as clickable link to Kleros Curate item - Add Kleros logo to tag badge - Migrate REACT_APP_ENVIRONMENT to VITE_ENVIRONMENT - Inject VITE_THE_GRAPH_API_KEY in CI workflows
…detection fix: issue #271 Arbitrum contract shown as account
…1167) Automatically detects proxy patterns and shows the implementation address as a clickable link. Merges the implementation ABI into the interaction panel so users can call implementation functions directly. - Add proxyDetection.ts utility supporting EIP-1967, EIP-1822 (UUPS), EIP-1967-Beacon, and EIP-1167 minimal proxy patterns - Add useProxyInfo hook wrapping detection with AppContext RPC URLs - Show proxy type and implementation address row in ContractInfoCard - Add ABI tab switcher (Implementation / Proxy) when both ABIs exist - Fetch implementation contract data from Sourcify when proxy detected - Add abi-tab-switcher CSS styles - Add i18n keys (proxyType, implementationAddress, implementationFunctions, proxyFunctions) to en, es, ja, pt-BR, zh locales Closes #266
Proxy detection fixes:
- Add legacy OZ AdminUpgradeabilityProxy slot (keccak256("org.zeppelinos.proxy.implementation"))
so Circle USDC (FiatTokenProxy) and other pre-EIP-1967 proxies are detected
- Use NetworkAdapter.getStorageAt/callContract instead of raw fetch calls,
so the configured RPC strategy (fallback/parallel) is used for proxy checks
- Add slotToAddress validation: top 12 bytes must be zero (ABI-encoded address)
to prevent false positives from contracts with incidental non-zero storage slots
- Run all four slot reads in parallel to reduce latency
- Add ProxyRpcClient interface satisfied by NetworkAdapter
EOA misclassification fixes:
- Pass pre-fetched addressData to fetchAddressWithType to avoid redundant
eth_getCode call; secondary RPC failures no longer silently downgrade
contracts to EOA
- When type detection fails or no RPC URL is configured, derive EOA/contract
from the already-fetched code instead of defaulting to "account"
Contract Details panel fix:
- Show the Contract Details section (ABI + interaction) whenever a proxy is
detected with a verified implementation ABI, even when the proxy contract
itself has no Sourcify entry
ERC20 tokens that are also proxies (e.g. USDC/FiatTokenProxy) now detect the proxy pattern and pass proxyInfo + implementationContractData to ContractInfoCard, enabling the implementation ABI tab switcher.
…on Sourcify When a proxy is detected but its implementation contract is not verified on Sourcify (e.g. Aave V3 Pool on Optimism), show a clear note explaining why no implementation ABI tab is available.
- Add useEtherscan hook fetching from Etherscan V2 API (single key, 60+ chains) - Add useContractVerification hook running Sourcify and Etherscan simultaneously; source is an array — empty means unverified, ["sourcify"], ["etherscan"], or both - Replace useSourcify calls in ContractDisplay, ERC20Display, ERC721Display, ERC1155Display with useContractVerification; add proxy detection to ERC721/ERC1155 - Show Sourcify and Etherscan as linked tag badges on the status row in ContractInfoCard, following the same style as Kleros tags (PR #277) - Compute verification URLs internally in ContractInfoCard (correct partial_match path for Sourcify; per-chain explorer URL for Etherscan); remove sourcifyUrl prop - Add Etherscan API key field to Settings (after Alchemy, before AI keys) - Add etherscan key to ApiKeys type and all 5 locale files - Fix double separator between EVM Version and Contract Details rows
…, hashes - New reusable CopyButton component with clipboard icon → checkmark feedback - LongString now shows copy button by default (copyable prop) - Added copy buttons to: EVM address header, BTC address, BTC block hash, BTC tx ID/witness hash - All EVM views using LongString (block hash, tx hash, addresses) get copy automatically - CSS with hover/focus-visible states Ticket 1 from UI/UX audit: copy buttons for hashes and addresses
… button - Added inline SearchBox so users can search directly from the empty state - Added descriptive help text explaining what can be searched - Added magnifying glass icon for visual clarity - Added 'Go Home' button as escape hatch - i18n keys added for en/es Ticket 2 from UI/UX audit: fix Search page dead end
…ry CTAs - Replaced technical error message with friendly explanation - Changed error text color from green to neutral (removed error-text-center class) - Added info icon for visual softness - Added 'Go to Homepage' and 'Browse Supporters' buttons as recovery paths - Added role='alert' for accessibility - i18n keys for en/es Ticket 3 from UI/UX audit: fix Profile error page
…g cards - Added 'Get Started' button to each pricing tier card - Highlighted Partner tier with 'Most Popular' badge and accent border - Cards use flex layout so CTA stays at bottom regardless of content height - CSS for badge positioning, recommended styling - i18n keys for en/es Ticket 4 from UI/UX audit: CTA buttons on Subscriptions pricing
… pages - New LoaderWithTimeout shows loading spinner for 15s then offers Retry + Go Home - Replaced plain Loader with LoaderWithTimeout in all BTC pages: Address, Block, Blocks, Mempool, Transaction, Transactions, Dashboard - Replaced in all EVM pages: Address, Block, Blocks, Txs, Tx, Network, Gas Tracker, Token Details - Users no longer stuck on infinite loading spinners Ticket 6 from UI/UX audit: timeout + error + retry states
- New SkeletonLoader module with SkeletonRow, SkeletonTable, SkeletonCard, SkeletonDashboard, SkeletonDetail - CSS shimmer animation for skeleton placeholders - EVM Network dashboard: replaced spinner with SkeletonDashboard (stat cards + table placeholders) - EVM Blocks list: replaced spinner with SkeletonTable (10 rows × 6 cols) - EVM Txs list: replaced spinner with SkeletonTable (10 rows × 7 cols) - Detail pages keep LoaderWithTimeout (single item loading) - Reduces layout shift (CLS) and improves perceived performance Ticket 7 from UI/UX audit: skeleton loaders
- New Breadcrumb component with aria-label, aria-current, semantic nav/ol - Integrated breadcrumbs into: EVM: Block detail, Transaction detail, Address detail BTC: Block detail, Transaction detail, Address detail - Path: Home › Chain › [Blocks/Transactions] › Current item - CSS with proper styling, hover states, separators Ticket 9 from UI/UX audit: breadcrumb navigation
- IsometricBlocks: skip spawning new cubes when prefers-reduced-motion is set - base.css: global reduced-motion media query disables all animations/transitions - Users with vestibular disorders or motion sensitivity get a static experience Ticket 11 from UI/UX audit: prefers-reduced-motion
- Dark mode textSecondary: #8a8f98 → #9ea3ad (~5.2:1 ratio) - Dark mode textTertiary: #5c6370 → #8b919b (~4.5:1 ratio) - Both now pass WCAG AA for normal text against dark backgrounds Ticket 12 from UI/UX audit: fix contrast for gray text
- Green outline (2px solid, 2px offset) on :focus-visible - Remove outline for mouse users via :focus:not(:focus-visible) - Keyboard users now see clear focus indicators on all interactive elements Ticket 13 from UI/UX audit: focus visible styles
- LoaderWithTimeout: aria-live='polite' + aria-busy on loading state - Timeout state: role='alert' for screen reader announcement - Screen readers now announce loading/timeout state changes Ticket 14 from UI/UX audit: accessible loading states
- Removed raw debug output (networkId/filter params displayed as text) - Added proper 'under development' page with: - Descriptive messaging about upcoming features - Icon for visual clarity - CTAs: 'View Gas Tracker', 'Back to Dashboard', 'Go Home' - No longer exposes internal parameters to end users Ticket 15 from UI/UX audit: fix ETH Mempool page
- 'subscribing a network' → 'becoming a subscriber' (less ambiguous) Ticket 17 from UI/UX audit: fix ambiguous CTA copy
feat: UX, accessibility, and loading-state improvements across Explorer
- useSourcify: add SourcifyV2Raw internal type and mapV2Response() to
correctly extract compilation fields (name, compilerVersion, evmVersion,
language, optimizer) from the nested 'compilation' object returned by
V2 API — these were previously undefined because the raw JSON was
assigned directly without mapping
- useSourcify: normalize match values ('exact_match' -> 'perfect')
- useSourcify: add proxyResolution field (isProxy, proxyType, implementations)
- useSourcify: remove dead code — SOURCIFY_API_BASE (V1 URL) and
useSourcifyFiles hook (never imported anywhere)
- ContractDisplay: merge Sourcify proxyResolution with RPC detection;
Sourcify provides the implementation address reliably, RPC provides
accurate Transparent vs UUPS distinction
- ContractDisplay: expose sourcifyImplName from proxyResolution so the
implementation contract name is available immediately without waiting
for a second verification fetch
- ContractDisplay: rename sourcifyData -> contractVerifiedData (also in
ERC20/721/1155Display) to reflect it may come from Etherscan fallback
- ContractInfoCard: add language, optimizerEnabled, optimizerRuns fields
and display rows; use sourcifyImplName as immediate name fallback
- index.tsx: only reset addressType when navigating to a new address
(use prevAddressRef); keeps display component mounted on background
re-fetches, preserving all hook state
- useProxyInfo: keep last known proxyInfo on RPC failure instead of
resetting to null, preventing verified impl data from disappearing
- i18n: add language, optimizer, optimizerEnabled, optimizerDisabled
keys in all 5 locales
…contract tabs - Derive sourceFiles from activeSourceData (same as activeABI) so implementation source code shows when on the Implementation tab - Suppress bottom bytecode section when contract-details-section already renders bytecode (prevents duplication for unverified proxy with verified implementation) - Add runtimeBytecode field to SourcifyContractDetails and map it from Sourcify V2 API response so bytecode switches with active tab - Add NetworkAdapter.getCode() for direct eth_getCode calls - Fetch implementation bytecode via RPC in ContractDisplay as fallback when Sourcify runtimeBytecode is unavailable (Etherscan-only contracts)
…tection feat(address): proxy contract detection + Etherscan verification source
.show-mobile-flex, .show-mobile-inline and .show-mobile-inline-flex had no default display:none outside the mobile media query, causing them to render on all screen sizes. This made the address hash appear duplicated on the address page (both the full desktop span and the truncated mobile span were visible simultaneously). Also ignores package-lock.json and .claude/plans/ in .gitignore.
…inks feat(seo): Add canonical and alternate links
Automatically tests and re-orders RPC endpoints by quality (privacy tier + latency) on first load, removing the need for manual sync. A rpcsSynced flag prevents re-running on every page load and is reset when the user clears cache data.
fix: pre-release fixes for v1.2.3
Replace internal footer links with external links to https://openscan-explorer.github.io/docs/
feat(settings): auto-sync RPCs by latency on first load
…of-docs refactor: remove about/contact/subscriptions pages in favor of docs site
|
🚀 Preview: https://pr-287--openscan.netlify.app |
The address page passes the route parameter (e.g. 'eth') as networkId to
display components, which call Number(networkId). Number('eth') returns NaN,
causing metadata fetches to use NaN as chainId (404s).
Fix: use existing getNetworkById() + getChainIdFromNetwork() to properly
resolve the slug to a numeric chainId before passing to display components.
…displays fix: resolve NaN chainId when networkId is a slug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Release v1.2.3-alpha — merges all features, fixes, and improvements accumulated in dev into main.
Related Issue
Type of Change
Changes Made
Features
Fixes
Accessibility
Refactoring
Checklist
npm run format:fixandnpm run lint:fixnpm run typecheckwith no errorsnpm run test:run