Skip to content

About

Independent open source explorer for Ink Mainnet and Sepolia.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

17 Commits

Folders and files

Repository files navigation

Ink Explorer

Ink Explorer is an open source project for the Ink community. You can use it to look up blocks, transactions, wallets, tokens and contracts on Ink Mainnet or Sepolia. The site gets historical data from public indexes and checks live chain status against local OP-Reth and OP Node instances when those are available.

The code is MIT licensed. You can run your own instance, fix a bug or adapt the explorer for another chain. See the fork guide before changing networks: some Ink and OP Stack behaviour is built into the source. This project is independent and is not an official Ink explorer.

Contract pages support ABI-based reads and wallet-confirmed writes, including proxy implementations and custom ABIs. The server does not hold keys or submit transactions on a user's behalf.

The interface uses English as its source language and provides translated page content, navigation and entity terminology in Chinese, Hindi, Spanish, French, Arabic, Bengali, Portuguese, Russian and Japanese. Project documentation is in English. Arabic uses a right-to-left layout. Locale-aware numbers, dates, canonical links and language alternatives are generated without a translation service.

Explorer coverage

  • Browse recent blocks and transactions with cursor pagination. Wallet addresses use deterministic pixel identicons; transaction pages show fees, transfers, logs and traces.
  • Inspect addresses, verified contracts, proxy implementations, tokens and NFT instances. Contract calls use an ABI and stay under the user's wallet control.
  • Search DEX pools by token, exchange, fee tier, liquidity or volume. Market figures come from a third-party data source and are labelled as estimates.
  • Follow Optimism bridge activity and ERC-4337 user operations, or export analytics as CSV.
  • Compare indexed history with local execution and rollup node status. The live view uses WebSocket updates and shows when a node is unavailable or behind.
  • Share route-specific pages with canonical URLs, social metadata and a multilingual sitemap.

Requirements

  • Node.js 22.12 or newer
  • npm
  • Google Chrome at /usr/bin/google-chrome for the browser suites
  • optional local Ink OP-Reth and OP Node JSON-RPC for independent live verification

Quick start

npm ci --include=dev
cp .env.example .env
npm run build
npm start

Open http://127.0.0.1:4188. The historical explorer works with the public defaults. If local nodes are absent, their health signals are shown as unavailable instead of being substituted with public data.

For PM2:

pm2 start ecosystem.config.cjs
pm2 save

Set PUBLIC_URL to the public HTTPS origin before production deployment. Keep local RPC ports bound to loopback or a private service network.

For the Sepolia worker, copy .env.sepolia.example to .env.sepolia before starting PM2. The two processes read separate environment files. See the deployment and fork guide for the exact settings and the changes needed for another chain.

Configuration

Variable Default Purpose
PORT 4188 HTTP/WebSocket listen port
INK_TESTNET_PORT 4190 Loopback Sepolia worker port for the main proxy
HOST 0.0.0.0 HTTP bind address; testnet worker uses loopback
INK_NETWORK mainnet sepolia selects chain 763373 and its upstreams
PUBLIC_URL request origin Canonical, sitemap and Open Graph origin
EXPLORER_BROWSER_ORIGIN empty Exact HTTPS origin allowed to read the API from a separate browser site
INK_PUBLIC_API_ORIGIN empty Public HTTPS API gateway, used only by the static hosting function
VITE_PUBLIC_API_ORIGIN empty Optional public API for other static hosts; default uses same-origin requests
WALLETCONNECT_PROJECT_ID empty Public Reown project ID returned by the API at runtime
VITE_WALLETCONNECT_PROJECT_ID empty Optional frontend build override for the same public project ID
INK_GATEWAY_PORT 4186 Optional API-only loopback gateway
INK_GATEWAY_UPSTREAM http://127.0.0.1:4188 Loopback explorer upstream for that gateway
BLOCKSCOUT_API Ink Blockscout v2 Indexed chain history
BLOCKSCOUT_STATS_API Ink Stats Service Counters and time series
CONTRACT_INFO_API Blockscout Contract Info for chain 57073 DEX pool market metadata
INK_RPC http://127.0.0.1:8545 Local OP-Reth JSON-RPC
INK_OP_NODE_RPC http://127.0.0.1:9545 Local OP Node JSON-RPC
INK_PUBLIC_RPC Ink public RPC Contract read/simulation fallback
INK_METRICS_URL http://127.0.0.1:9001/metrics Local execution metrics endpoint
INK_NODE_DATA_DIR empty Optional local node storage path for disk usage
INK_L1_FAILOVER_STATUS http://127.0.0.1:18545/readyz Optional local L1 relay health

Data and caching

A static frontend does not run server/server.mjs. On Vercel, /api/* and /testnet/api/* use api/gateway.mjs, which forwards to INK_PUBLIC_API_ORIGIN. Configure a public HTTPS reverse proxy (or Tailscale Funnel, not tailnet-only Serve) to the loopback server/public-gateway.mjs. Its fixed destination exposes explorer API routes and the live WebSocket; node RPC, metrics and static filesystem routes remain private. Set EXPLORER_BROWSER_ORIGIN on both workers to the exact site origin so explicit simulations and submissions pass their origin checks. The browser uses same-origin HTTP without a VPN or local-network permission. The WebSocket is discovered through /api/live/config; public HTTP snapshots keep live data updating if WebSockets are blocked.

Existing deployments with a server-side VITE_API_ORIGIN pointing to a .ts.net:4189 Serve origin migrate through the public port 8443 and /ink mount. New installations should set INK_PUBLIC_API_ORIGIN explicitly. Never put credentials or local node URLs in VITE_* variables. API requests must be tested through public DNS from outside the tailnet; successful tests on a VPN-connected machine are insufficient. Static hosting limits apply to source uploads (the proxy accepts up to 4 MiB). Deep links continue to use the single-page interface.

Browser wallets connect directly through EIP-6963 discovery, with a legacy EIP-1193 fallback. When several wallets are installed, users choose the provider explicitly; duplicate and late announcements are handled without requesting accounts during discovery. This path requires no connection-service account, project ID, relay or message signature. On mobile, use the wallet's built-in browser.

WalletConnect QR is optional: its button is offered only when a valid project ID is configured. WalletConnect's core wallet connections are free, and require a public project ID from the WalletConnect Dashboard. Configure WALLETCONNECT_PROJECT_ID on both API workers (or VITE_WALLETCONNECT_PROJECT_ID before building) and authorize the site's actual domains. Runtime configuration does not require another frontend build. Relay preparation times out after 30 seconds; an unauthorized origin shows a localized error immediately. Once the QR appears, users have three minutes to confirm or can cancel at any time. The QR contains a temporary pairing URI and is never logged. Connections request transaction permission only; the explorer does not request message signatures or private keys. The SDK is pinned to the Apache-2.0 release, with security fixes pinned in transitive dependencies; dependency upgrades must recheck licensing and advisories.

/approvals and the address Approvals section discover standard ERC-20/ERC-721 Approval and ERC-721/ERC-1155 ApprovalForAll events, then reread current permissions on a ready RPC at a canonical block. Saturated index ranges are split without skipping boundary events. Failed or cancelled scans remain explicitly incomplete. Only the owner on the selected chain can simulate and confirm a zero-value revoke; receipt success is followed by a fresh state read. Non-standard contracts, missing indexed events and Permit2 permissions are outside this discovery scope.

Ink Blockscout API v2 and Stats Service provide network-wide indexed history. Blockscout Contract Info supplies pool discovery and market estimates. OP-Reth and OP Node provide only the operator's independent live checks.

Public JSON responses are cached in memory and on disk. A verified disk response can be served for up to 24 hours when the public index rate-limits or becomes unavailable. NFT images are downloaded on first display into data/media-cache and then served from the same origin. Private-network targets, non-HTTPS sources, unsupported image types and files over 8 MB are rejected. Background pruning removes old files and aims to keep upstream snapshots under 256 MB and media under 512 MB; active writes can briefly exceed those limits. Cache folders are excluded from version control.

Pool prices, liquidity, market capitalisation and volume are third-party estimates. NFT metadata can be mutable. The UI labels both risks and never presents them as investment advice.

Testing

The complete release protocol is documented in docs/TEST_PROTOCOL.md. The final findings and scope are documented in docs/EXPLORER_AUDIT.md. Run npm run test:release against an isolated review instance for a logged campaign across all suites. Partial runs cannot certify a release.

With the production server running on port 4188:

npm run check
npm run build
npm run test:data
npm run test:integrity
npm run test:activity
npm run test:activity-server
npm run test:activity-live
npm run test:ws
npm run test:network-live
npm run test:ui
npm run test:a11y
npm run test:i18n
npm run test:security
npm run test:identicons
npm run test:content
npm run test:performance
npm run test:lighthouse
npm run test:loading
npm run test:address-loading
npm run test:chain-reconciliation
npm run test:contracts
npm run test:approvals
npm run test:public-proxy
npm run test:networks
npm run test:node-testnet
npm run test:node-readiness
npm run test:upstream-cache
npm run test:layout
npm run test:responsive
npm run test:space
npm run test:style

The browser tests cover routes at desktop, tablet and mobile widths, plus menus, tabs, pagination, media, contract source, pools, analytics and localization. test:layout checks 20 route states at 12 widths, including long NFT lists. test:responsive checks each CSS breakpoint at nearby widths, keyboard and touch interactions, and empty or failed network responses. test:style compares rendered surfaces and controls with the shared design rules. test:content checks copy, metadata and labels; test:a11y checks serious and critical Axe findings. Browser tests need Chrome and a running production server.

Lighthouse runs mobile and desktop audits on six representative routes and writes reports under reports/lighthouse/. Set BASE_URL, LIGHTHOUSE_DIR, LIGHTHOUSE_ROUTES or LIGHTHOUSE_PROFILES to change the run. Its scores are lab measurements on your machine. test:loading delays API responses to check the loading state.

CI runs the dependency audit, TypeScript check, production build, deterministic chain-data/filter/node-readiness tests and HTTP security checks. Browser suites need Chrome and live upstream APIs; WebSocket and node-health assertions need synced Ink nodes. Run those suites against the release build before deployment.

On Transactions → Advanced filters, combine activity type, method selector, sender/recipient, token contract, dates and decimal amounts. Amount filters use ETH or token units; CSV keeps raw values and exports the displayed page. Criteria survive reload and pagination. Dates follow your device’s time zone.

API surface

  • GET /api/health — service and WebSocket health
  • GET /api/live/status — current stream state
  • WS /api/live — ink-observer.live.v1 welcome, network and block frames
  • GET /api/overview and /api/network — composed overview and local node status
  • GET /api/explorer/* — allow-listed Blockscout-compatible reads
  • GET /api/stats/* — statistics catalogue, counters and chart reads
  • GET /api/names/* — name protocols, domains and registration events
  • GET /api/dapps — selected network’s application catalogue
  • POST /api/verification/submit and GET /api/verification/status/:ticket — explicit contract-source publication and progress
  • POST /api/public-tags/submit — private proposals for operator review
  • GET /api/contract-info/pools[/:address[/check]] — pool list/detail/cross-link data
  • GET /api/media?url=… — validated same-origin NFT/token image cache
  • POST /api/contract-rpc — restricted eth_call, eth_estimateGas, chain/head/code/receipt reads; signing and broadcast remain in the user's wallet

Testnet and contract interaction

The network selector opens /testnet/ for Ink Sepolia. The main server proxies this prefix to an isolated worker at 127.0.0.1:4190; the worker uses Sepolia Blockscout, statistics and contract metadata. Its local node ports are 8645 (execution) and 9645 (rollup). Mainnet remains on 8545/9545. The PM2 ecosystem file starts both explorer workers. Use pm2 startOrReload ecosystem.config.cjs --update-env; avoid importing an unrelated shell's PORT through a bare pm2 restart --update-env.

All testnet API and WebSocket paths carry the /testnet prefix. Network changes reload the page to discard state from the previous chain. Indexed history remains usable during node sync; network health and live blocks only represent the local node. Contract reads explicitly identify the public RPC fallback when the local node is not ready. The server never forwards signing, admin or transaction-broadcast methods.

On a contract address, open Read contract or Write contract. Select its ABI, an indexed proxy implementation, or paste a custom JSON ABI. Proxy calls target the proxy address. Writes require a browser wallet or WalletConnect, a successful simulation and confirmation inside that wallet. Large integers in JSON arrays must be quoted; payable amounts use ETH and other integer arguments use raw base units. Source verification runs inside the explorer and supports the Solidity/Vyper methods enabled by the index. WalletConnect QR requires a configured public project ID and an authorized site origin.

npm run test:contracts starts an isolated Anvil chain and explorer on ports 18546, 18547 and 4192, compiles the Solidity fixtures and verifies actual EVM state changes through the browser workflow. It never submits to public mainnet/testnet. It requires the development dependencies and Chrome. npm run test:networks audits both real networks with Chromium, Firefox and WebKit; install engines with npx playwright install firefox webkit and their OS dependencies. If your host needs a custom library path for those browsers, set INK_BROWSER_LIBS.

See docs/ARCHITECTURE.md for source boundaries and security decisions. See docs/API.md for endpoint shapes, errors and the WebSocket protocol. Use docs/FORKING.md to deploy the explorer elsewhere or adapt it to another chain.

Project policy

Want to help? Start with the contributor guide. Documentation fixes, translations, accessibility improvements and reproducible bug reports are welcome; local Ink nodes are optional. Check issues labelled good first issue or help wanted when available. Use GitHub Discussions for questions and early ideas, and an issue for a specific change. Contributors follow the Code of Conduct. Report vulnerabilities as described in SECURITY.md, without posting exploit details publicly.

Ink Explorer is not affiliated with or endorsed by Ink, Kraken, Blockscout, GeckoTerminal or any listed protocol. “Ink” and third-party marks belong to their respective owners.

See third-party notices for the Ink mark, bundled fonts and external data sources.

Licensed under the MIT License.

Additional explorer pages

Accounts, internal transactions, token transfers, deposits, withdrawals, batches, dispute games, user operations, names, gas, Dapps and the full statistics catalogue are available from Advanced → Explorer tools. Detail destinations and wallet receipts stay inside this explorer. The public index remains a data source.

Source verification requires consent to publish the submitted contract sources. No wallet signature or transaction is required. Standard compiler JSON preserves optimizer, libraries and compilation settings. Single-file and multipart inputs also expose these settings. Never upload confidential contract sources.

Public-label proposals are stored privately until an operator approves them. Use npm run tags:review -- 57073 list (or 763373) on the server, then npm run tags:review -- 57073 approve <request-id> or reject. The list includes private contact details: keep it on the operator’s machine. Approval publishes only labels and their chosen public metadata; it does not verify contract code. The queue belongs to this explorer, independently of Blockscout’s moderation.

About

Independent open source explorer for Ink Mainnet and Sepolia.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages