mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
/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.
217 lines
8.0 KiB
TypeScript
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>;
|
|
}
|