Files
explore/nextjs/nextjs-routes.d.ts
zeekay 87aa0fa367 chains: read each chain from that chain, and list the ones this network runs
/chains showed fifteen rows on every network, from a hardcoded table. Four of
them — T, R, I, O — are registered on no network at all; the node answers
"there is no ID with alias: T". A fifth, M, runs on devnet alone. And every
/chains/<slug> page printed the same four numbers: the primary network's
validator count, its total stake, its chain count, its threshold. Nothing on
Q-Chain's page was about Q-Chain. Fifteen pages, one set of facts.

The network already knows its own answer. platform.getBlockchains is the chain
list, and it is per-network for free: mainnet and testnet report nine chains,
devnet reports ten including M. That is what /chains lists now, joined with
configs/app/primaryChains.ts for presentation only — a chain the network
reports and we have no metadata for still gets a row, because the network is
the source of truth and our table is not.

Three facts per chain, each read from that chain:

  * the blockchain ID, from the registry — the thing that actually tells one
    chain from another, and it was already on screen while the numbers above
    it were not
  * whether the node has bootstrapped it, from info.isBootstrapped, which the
    gateway routes for every chain. This is how Q-Chain's page now says
    Syncing where the other nine say Bootstrapped: Q has not come up on any of
    the three networks and is the sole reason all three report healthy:false
  * its head, in its own dialect — eth_blockNumber for C, platform.getHeight
    for P, xvm.getHeight for X. Not avm: that service is gone from this build,
    and asking it returns "can't find service" rather than a height

Validators are the P-Chain's model, so they render on the P-Chain and nowhere
else. The head is labelled for the model it comes from — the X-Chain's is an
accepted height, not a block height.

Where a chain has no head to read, it says so. The gateway routes exactly P, X
and C on all three networks; D, A, B, Z, G, K and Q are registered and
bootstrapped on the node but their RPC 404s from a browser. Proof it is the
route and not the chain: C-Chain's own blockchain ID, /v1/bc/25td8att…/rpc,
404s while /v1/bc/C/rpc returns a height — same chain, same node. Those pages
read "No public RPC" and say plainly that the chain is registered and running
but not published. A zero there would have read as a measurement.

One proxy replaces the P-only one. /v1/pchain hardcoded /v1/bc/P; /v1/node/
<endpoint> resolves the endpoint against the primary-chain table and never
treats it as a URL. A chain the gateway does not route comes back 200 carrying
a JSON-RPC error rather than 502 — nothing is broken, and 502 put a red failed
request in the console of eight of the ten chain pages.

Deleted: CHAIN_INDEXER_URLS and the hook that read it — fifteen hostnames of
the shape api-indexer-<x>chain.lux.network, none of which resolve. Fifteen of
fifteen NXDOMAIN. It fetched them on every chain page and rendered the null.

Measured on mainnet, 1440x900 and 390x844, fresh context per URL: 20 of 20
chain/screen rows agree with RPC on both status and head — C-Chain 1,107,826
against a live head bracketed at 1,107,822..1,107,829, P and X at 0, seven
reading No public RPC, Q Syncing while the rest are Bootstrapped. /chains
lists the same ten chains the P-Chain reports, and 10 of 10 row links reach a
real page. Zero 4xx or 5xx from our own origin.
2026-08-08 07:32:01 -07:00

217 lines
8.0 KiB
TypeScript

// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// This file will be automatically regenerated when your Next.js server is running.
// nextjs-routes version: 1.0.8
/* eslint-disable */
// prettier-ignore
declare module "nextjs-routes" {
export type Route =
| StaticRoute<"/404">
| StaticRoute<"/account/api-key">
| StaticRoute<"/account/custom-abi">
| StaticRoute<"/account/merits">
| StaticRoute<"/account/tag-address">
| StaticRoute<"/account/verified-addresses">
| StaticRoute<"/account/watchlist">
| StaticRoute<"/accounts">
| DynamicRoute<"/accounts/label/[slug]", { "slug": string }>
| DynamicRoute<"/address/[hash]/contract-verification", { "hash": string }>
| DynamicRoute<"/address/[hash]", { "hash": string }>
| StaticRoute<"/advanced-filter">
| StaticRoute<"/ai">
| StaticRoute<"/api/ai">
| StaticRoute<"/api/config">
| StaticRoute<"/api/healthz">
| StaticRoute<"/api/log">
| StaticRoute<"/api/metrics">
| StaticRoute<"/api/monitoring/invalid-api-schema">
| DynamicRoute<"/api/node/[endpoint]", { "endpoint": string }>
| StaticRoute<"/api/proxy">
| DynamicRoute<"/api/tokens/[hash]/instances/[id]/media-type", { "hash": string; "id": string }>
| StaticRoute<"/api-docs">
| DynamicRoute<"/apps/[id]", { "id": string }>
| StaticRoute<"/apps">
| StaticRoute<"/auth/callback">
| DynamicRoute<"/batches/[number]", { "number": string }>
| DynamicRoute<"/batches/celestia/[height]/[commitment]", { "height": string; "commitment": string }>
| StaticRoute<"/batches">
| DynamicRoute<"/blobs/[hash]", { "hash": string }>
| DynamicRoute<"/block/[height_or_hash]", { "height_or_hash": string }>
| DynamicRoute<"/block/countdown/[height]", { "height": string }>
| StaticRoute<"/block/countdown">
| StaticRoute<"/blocks">
| StaticRoute<"/bridge">
| DynamicRoute<"/cc/tx/[hash]", { "hash": string }>
| DynamicRoute<"/chain/[chain_slug]/accounts/label/[slug]", { "chain_slug": string; "slug": string }>
| DynamicRoute<"/chain/[chain_slug]/advanced-filter", { "chain_slug": string }>
| DynamicRoute<"/chain/[chain_slug]/block/[height_or_hash]", { "chain_slug": string; "height_or_hash": string }>
| DynamicRoute<"/chain/[chain_slug]/block/countdown/[height]", { "chain_slug": string; "height": string }>
| DynamicRoute<"/chain/[chain_slug]/block/countdown", { "chain_slug": string }>
| DynamicRoute<"/chain/[chain_slug]/csv-export", { "chain_slug": string }>
| DynamicRoute<"/chain/[chain_slug]/op/[hash]", { "chain_slug": string; "hash": string }>
| DynamicRoute<"/chain/[chain_slug]/token/[hash]", { "chain_slug": string; "hash": string }>
| DynamicRoute<"/chain/[chain_slug]/token/[hash]/instance/[id]", { "chain_slug": string; "hash": string; "id": string }>
| DynamicRoute<"/chain/[chain_slug]/tx/[hash]", { "chain_slug": string; "hash": string }>
| DynamicRoute<"/chain/[chain_slug]/visualize/sol2uml", { "chain_slug": string }>
| DynamicRoute<"/chains/[slug]", { "slug": string }>
| StaticRoute<"/chains">
| StaticRoute<"/contract-verification">
| DynamicRoute<"/cross-chain-tx/[id]", { "id": string }>
| StaticRoute<"/csv-export">
| StaticRoute<"/deposits">
| StaticRoute<"/dex">
| StaticRoute<"/dispute-games">
| StaticRoute<"/ecosystems">
| DynamicRoute<"/epochs/[number]", { "number": string }>
| StaticRoute<"/epochs">
| DynamicRoute<"/essential-dapps/[id]", { "id": string }>
| StaticRoute<"/gas-tracker">
| StaticRoute<"/hot-contracts">
| StaticRoute<"/">
| StaticRoute<"/internal-txs">
| StaticRoute<"/interop-messages">
| StaticRoute<"/mud-worlds">
| DynamicRoute<"/name-services/clusters/[name]", { "name": string }>
| DynamicRoute<"/name-services/domains/[name]", { "name": string }>
| StaticRoute<"/name-services">
| DynamicRoute<"/op/[hash]", { "hash": string }>
| DynamicRoute<"/operation/[id]", { "id": string }>
| StaticRoute<"/operations">
| StaticRoute<"/ops">
| StaticRoute<"/output-roots">
| DynamicRoute<"/pools/[hash]", { "hash": string }>
| StaticRoute<"/pools">
| StaticRoute<"/public-tags/submit">
| StaticRoute<"/search-results">
| StaticRoute<"/sprite">
| DynamicRoute<"/stats/[id]", { "id": string }>
| StaticRoute<"/stats">
| DynamicRoute<"/token/[hash]", { "hash": string }>
| DynamicRoute<"/token/[hash]/instance/[id]", { "hash": string; "id": string }>
| StaticRoute<"/token-transfers">
| StaticRoute<"/tokens">
| DynamicRoute<"/tx/[hash]", { "hash": string }>
| StaticRoute<"/txn-withdrawals">
| StaticRoute<"/txs">
| DynamicRoute<"/txs/kettle/[hash]", { "hash": string }>
| StaticRoute<"/uptime">
| DynamicRoute<"/validators/[id]", { "id": string }>
| StaticRoute<"/validators">
| StaticRoute<"/verified-contracts">
| StaticRoute<"/visualize/sol2uml">
| StaticRoute<"/withdrawals">;
interface StaticRoute<Pathname> {
pathname: Pathname;
query?: Query | undefined;
hash?: string | null | undefined;
}
interface DynamicRoute<Pathname, Parameters> {
pathname: Pathname;
query: Parameters & Query;
hash?: string | null | undefined;
}
interface Query {
[key: string]: string | string[] | undefined;
};
export type RoutedQuery<P extends Route["pathname"]> = Extract<
Route,
{ pathname: P }
>["query"];
export type Locale = undefined;
/**
* A typesafe utility function for generating paths in your application.
*
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
}
// prettier-ignore
declare module "next/link" {
import type { Route } from "nextjs-routes";
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type {
AnchorHTMLAttributes,
DetailedReactHTMLElement,
MouseEventHandler,
PropsWithChildren,
} from "react";
export * from "next/dist/client/link";
type Query = { query?: { [key: string]: string | string[] | undefined } };
type StaticRoute = Exclude<Route, { query: any }>["pathname"];
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Query;
locale?: false;
}
type LinkReactElement = DetailedReactHTMLElement<
{
onMouseEnter?: MouseEventHandler<Element> | undefined;
onClick: MouseEventHandler;
href?: string | undefined;
ref?: any;
},
HTMLElement
>;
declare function Link(props: PropsWithChildren<LinkProps>): LinkReactElement;
export default Link;
}
// prettier-ignore
declare module "next/router" {
import type { Locale, Route, RoutedQuery } from "nextjs-routes";
import type { NextRouter as Router } from "next/dist/client/router";
export * from "next/dist/client/router";
export { default } from "next/dist/client/router";
type NextTransitionOptions = NonNullable<Parameters<Router["push"]>[2]>;
type StaticRoute = Exclude<Route, { query: any }>["pathname"];
type Query = { query?: { [key: string]: string | string[] | undefined } };
interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
locale?: false;
}
export type NextRouter<P extends Route["pathname"] = Route["pathname"]> =
Extract<Route, { pathname: P }> &
Omit<
Router,
| "push"
| "replace"
| "locale"
| "locales"
| "defaultLocale"
| "domainLocales"
> & {
defaultLocale?: undefined;
domainLocales?: undefined;
locale?: Locale;
locales?: undefined;
push(
url: Route | StaticRoute | Query,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
replace(
url: Route | StaticRoute | Query,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
route: P;
};
export function useRouter<P extends Route["pathname"]>(): NextRouter<P>;
}