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.
272 lines
10 KiB
JSON
272 lines
10 KiB
JSON
{
|
|
"name": "@luxfi/explore",
|
|
"version": "1.1.30",
|
|
"private": false,
|
|
"homepage": "https://github.com/luxfi/explore#readme",
|
|
"engines": {
|
|
"node": ">=22.14.0",
|
|
"npm": ">=10.9.0"
|
|
},
|
|
"scripts": {
|
|
"dev": "./tools/scripts/dev.sh",
|
|
"dev:preset": "./tools/scripts/dev.preset.sh",
|
|
"dev:preset:sync": "tsc -p ./tools/preset-sync/tsconfig.json && node ./tools/preset-sync/index.js",
|
|
"build": "node scripts/generate-well-known.js && next build --webpack",
|
|
"build:next": "./deploy/scripts/download_assets.sh ./public/assets/configs && pnpm svg:build-sprite && ./deploy/scripts/make_envs_script.sh && node scripts/generate-well-known.js && next build --webpack",
|
|
"wellknown:generate": "node scripts/generate-well-known.js",
|
|
"wellknown:check": "node scripts/generate-well-known.js --check",
|
|
"build:docker": "./tools/scripts/build.docker.sh",
|
|
"start": "next start",
|
|
"start:docker:local": "docker run -p 3000:3000 --env-file .env.local lux-explore:local",
|
|
"start:docker:preset": "./tools/scripts/docker.preset.sh",
|
|
"lint:eslint": "eslint .",
|
|
"lint:eslint:fix": "eslint . --fix",
|
|
"lint:tsc": "tsc -p ./tsconfig.json",
|
|
"lint:cspell": "cspell . --no-must-find-files",
|
|
"lint:license:check": "license-report > ./license.json && license-report-check --source=./license.json --output=table --forbidden=n/a",
|
|
"lint:envs-validator:test": "cd ./deploy/tools/envs-validator && ./test.sh",
|
|
"prepare": "husky install",
|
|
"icons:sync": "node tools/icons/from-lucide.mjs && pnpm svg:build-sprite",
|
|
"svg:format": "svgo -r --config svgo.config.format.js ./icons",
|
|
"svg:build-sprite": "./deploy/scripts/build_sprite.sh",
|
|
"test:pw": "./tools/scripts/pw.sh",
|
|
"test:pw:local": "export NODE_PATH=$(pwd)/node_modules && pnpm test:pw",
|
|
"test:pw:docker": "docker run --rm --ipc=host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-noble ./tools/scripts/pw.docker.sh",
|
|
"test:pw:docker:deps": "docker run --rm --ipc=host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.57.0-noble ./tools/scripts/pw.docker.deps.sh",
|
|
"test:pw:ci": "pnpm test:pw --project=$PW_PROJECT",
|
|
"test:pw:detect-affected": "node ./deploy/tools/affected-tests/index.js",
|
|
"test:vitest": "vitest",
|
|
"favicon:generate:dev": "./tools/scripts/favicon-generator.dev.sh",
|
|
"og-image:generate:dev": "./tools/scripts/og-image-generator.dev.sh",
|
|
"sitemap:generate:dev": "./tools/scripts/sitemap-generator.dev.sh",
|
|
"monitoring:prometheus:local": "docker run --name lux_prometheus -d -p 127.0.0.1:9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus",
|
|
"monitoring:grafana:local": "docker run -d -p 4000:3000 --name=lux_grafana --user $(id -u) --volume $(pwd)/grafana:/var/lib/grafana grafana/grafana-enterprise"
|
|
},
|
|
"dependencies": {
|
|
"@dynamic-labs/ethereum": "4.52.2",
|
|
"@dynamic-labs/sdk-react-core": "4.52.2",
|
|
"@dynamic-labs/wagmi-connector": "4.52.2",
|
|
"@helia/verified-fetch": "2.6.12",
|
|
"@luxfi/bens-types": "1.4.3",
|
|
"@luxfi/interchain-indexer-types": "0.0.10",
|
|
"@luxfi/multichain-aggregator-types": "2.1.2",
|
|
"@luxfi/points-types": "1.4.2",
|
|
"@luxfi/stats-types": "2.11.1",
|
|
"@luxfi/tac-operation-lifecycle-types": "1.1.0",
|
|
"@luxfi/ui": "7.4.10",
|
|
"@luxfi/visualizer-types": "0.2.0",
|
|
"@luxfi/zetachain-cctx-types": "1.0.1",
|
|
"@metamask/post-message-stream": "^7.0.0",
|
|
"@metamask/providers": "^10.2.1",
|
|
"@monaco-editor/react": "^4.7.0",
|
|
"@multisender.app/multisender-react-widget": "0.2.3",
|
|
"@nouns/assets": "^0.10.0",
|
|
"@nouns/sdk": "^1.2.0",
|
|
"@opentelemetry/api": "^1.4.1",
|
|
"@opentelemetry/auto-instrumentations-node": "0.43.0",
|
|
"@opentelemetry/exporter-jaeger": "1.27.0",
|
|
"@opentelemetry/exporter-metrics-otlp-proto": "0.49.1",
|
|
"@opentelemetry/exporter-trace-otlp-http": "0.49.1",
|
|
"@opentelemetry/resources": "1.22.0",
|
|
"@opentelemetry/sdk-node": "0.49.1",
|
|
"@opentelemetry/sdk-trace-node": "1.22.0",
|
|
"@opentelemetry/semantic-conventions": "1.22.0",
|
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
"@radix-ui/react-avatar": "^1.1.11",
|
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
"@radix-ui/react-label": "^2.1.8",
|
|
"@radix-ui/react-popover": "^1.1.15",
|
|
"@radix-ui/react-progress": "^1.1.8",
|
|
"@radix-ui/react-radio-group": "^1.3.8",
|
|
"@radix-ui/react-select": "^2.2.6",
|
|
"@radix-ui/react-slider": "^1.3.6",
|
|
"@radix-ui/react-slot": "^1.2.4",
|
|
"@radix-ui/react-switch": "^1.2.6",
|
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
"@reown/appkit": "1.7.20",
|
|
"@reown/appkit-adapter-wagmi": "1.7.20",
|
|
"@rollbar/react": "0.12.1",
|
|
"@scure/base": "1.1.9",
|
|
"@slise/embed-react": "^2.2.0",
|
|
"@specify-sh/sdk": "0.4.2",
|
|
"@tailwindcss/postcss": "^4.2.1",
|
|
"@tanstack/react-query": "5.55.4",
|
|
"@tanstack/react-query-devtools": "5.55.4",
|
|
"@uidotdev/usehooks": "2.4.1",
|
|
"airtable": "^0.12.2",
|
|
"bignumber.js": "^9.1.0",
|
|
"blo": "^1.1.1",
|
|
"brotli-compress": "1.3.3",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"crypto-js": "^4.2.0",
|
|
"d3": "^7.6.1",
|
|
"d3-sankey": "^0.12.3",
|
|
"dappscout-iframe": "0.4.0",
|
|
"dayjs": "^1.11.5",
|
|
"dom-to-image": "^2.6.0",
|
|
"es-toolkit": "1.39.10",
|
|
"focus-visible": "^5.2.0",
|
|
"gradient-avatar": "git+https://github.com/blockscout/gradient-avatar.git",
|
|
"graphiql": "^4.1.2",
|
|
"graphql": "^16.8.1",
|
|
"graphql-ws": "^5.11.3",
|
|
"js-cookie": "^3.0.1",
|
|
"magic-bytes.js": "1.8.0",
|
|
"mixpanel-browser": "2.67.0",
|
|
"monaco-editor": "^0.34.1",
|
|
"next": "16.1.6",
|
|
"next-themes": "0.4.4",
|
|
"nextjs-routes": "^1.0.8",
|
|
"node-fetch": "^3.2.9",
|
|
"papaparse": "^5.3.2",
|
|
"path-to-regexp": "8.1.0",
|
|
"phoenix": "^1.6.15",
|
|
"pino-http": "^8.2.1",
|
|
"pino-pretty": "^9.1.1",
|
|
"postcss": "^8.5.8",
|
|
"prom-client": "15.1.1",
|
|
"qrcode": "^1.5.1",
|
|
"react": "19.2.4",
|
|
"react-device-detect": "^2.2.3",
|
|
"react-dom": "19.2.4",
|
|
"react-google-recaptcha": "3.1.0",
|
|
"react-hook-form": "7.52.1",
|
|
"react-identicons": "^1.2.5",
|
|
"react-intersection-observer": "^9.5.2",
|
|
"react-jazzicon": "^1.0.4",
|
|
"react-native-web": "^0.21.2",
|
|
"react-number-format": "^5.3.1",
|
|
"react-scroll": "^1.8.7",
|
|
"rollbar": "2.26.5",
|
|
"sonner": "^2.0.7",
|
|
"swagger-ui-react": "5.30.3",
|
|
"tailwind-merge": "^3.5.0",
|
|
"tailwindcss": "^4.2.1",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"use-font-face-observer": "^1.3.0",
|
|
"valibot": "1.2.0",
|
|
"viem": "2.41.2",
|
|
"wagmi": "2.19.5",
|
|
"xss": "^1.0.14"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/compat": "1.2.2",
|
|
"@eslint/js": "9.14.0",
|
|
"@hanzogui/lucide-icons-2": "7.3.0",
|
|
"@next/bundle-analyzer": "16.1.6",
|
|
"@next/eslint-plugin-next": "16.1.6",
|
|
"@openzeppelin/contracts": "5.4.0",
|
|
"@playwright/experimental-ct-react": "1.57.0",
|
|
"@playwright/test": "1.57.0",
|
|
"@stylistic/eslint-plugin": "5.2.3",
|
|
"@svgr/webpack": "^6.5.1",
|
|
"@tanstack/eslint-plugin-query": "5.91.2",
|
|
"@testing-library/react": "^14.0.0",
|
|
"@total-typescript/ts-reset": "^0.4.0",
|
|
"@types/crypto-js": "^4.1.1",
|
|
"@types/csp-dev": "^1.0.0",
|
|
"@types/d3": "^7.4.0",
|
|
"@types/d3-sankey": "^0.12.5",
|
|
"@types/dom-to-image": "^2.6.4",
|
|
"@types/js-cookie": "^3.0.2",
|
|
"@types/mixpanel-browser": "^2.38.1",
|
|
"@types/node": "20.16.7",
|
|
"@types/papaparse": "^5.3.5",
|
|
"@types/phoenix": "^1.5.4",
|
|
"@types/qrcode": "^1.5.0",
|
|
"@types/react": "19.2.14",
|
|
"@types/react-dom": "19.2.3",
|
|
"@types/react-google-recaptcha": "^2.1.5",
|
|
"@types/react-scroll": "^1.8.4",
|
|
"@types/swagger-ui-react": "5.18.0",
|
|
"@types/ws": "^8.5.3",
|
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
"@vitejs/plugin-react": "^4.0.0",
|
|
"cspell": "9.6.4",
|
|
"css-loader": "^6.7.3",
|
|
"dotenv-cli": "^6.0.0",
|
|
"esbuild": "0.25.12",
|
|
"eslint": "9.39.2",
|
|
"eslint-config-next": "16.1.6",
|
|
"eslint-plugin-consistent-default-export-name": "^0.0.15",
|
|
"eslint-plugin-import": "2.31.0",
|
|
"eslint-plugin-import-helpers": "2.0.1",
|
|
"eslint-plugin-jsx-a11y": "6.10.2",
|
|
"eslint-plugin-playwright": "2.0.1",
|
|
"eslint-plugin-react": "7.37.5",
|
|
"eslint-plugin-react-hooks": "5.0.0",
|
|
"eslint-plugin-regexp": "2.6.0",
|
|
"eslint-plugin-vitest": "0.5.4",
|
|
"globals": "15.12.0",
|
|
"husky": "^8.0.0",
|
|
"jsdom": "27.3.0",
|
|
"license-report": "6.8.1",
|
|
"license-report-check": "0.1.2",
|
|
"lint-staged": ">=10",
|
|
"mockdate": "^3.0.5",
|
|
"style-loader": "^3.3.1",
|
|
"svg-icons-cli": "0.0.8",
|
|
"svgo": "^2.8.0",
|
|
"ts-node": "^10.9.1",
|
|
"typescript": "5.9.3",
|
|
"typescript-eslint": "8.41.0",
|
|
"vite-plugin-svgr": "^2.2.2",
|
|
"vite-tsconfig-paths": "5.1.4",
|
|
"vitest": "4.0.15",
|
|
"vitest-fetch-mock": "0.4.5",
|
|
"ws": "^8.17.1"
|
|
},
|
|
"lint-staged": {
|
|
"*.{js,jsx,ts,tsx}": "eslint --cache --fix"
|
|
},
|
|
"pnpm": {
|
|
"overrides": {
|
|
"ws": "8.17.1",
|
|
"axios": "1.12.0",
|
|
"tar-fs": "2.1.4",
|
|
"node-forge": "1.3.2",
|
|
"brace-expansion": "1.1.12",
|
|
"js-yaml": "4.1.1",
|
|
"@noble/hashes": "1.8.0",
|
|
"@ipshipyard/node-datachannel": "link:./stubs/node-datachannel",
|
|
"@hanzogui/adapt": "3.0.2",
|
|
"@hanzogui/animate": "3.0.2",
|
|
"@hanzogui/animate-presence": "3.0.2",
|
|
"@hanzogui/compose-refs": "3.0.2",
|
|
"@hanzogui/constants": "3.0.2",
|
|
"@hanzogui/core": "3.0.2",
|
|
"@hanzogui/create-context": "3.0.2",
|
|
"@hanzogui/dismissable": "3.0.2",
|
|
"@hanzogui/floating": "3.0.2",
|
|
"@hanzogui/focus-scope": "3.0.2",
|
|
"@hanzogui/get-font-sized": "3.0.2",
|
|
"@hanzogui/get-token": "3.0.2",
|
|
"@hanzogui/helpers": "3.0.2",
|
|
"@hanzogui/is-equal-shallow": "3.0.1",
|
|
"@hanzogui/polyfill-dev": "3.0.2",
|
|
"@hanzogui/popover": "3.0.2",
|
|
"@hanzogui/popper": "3.0.2",
|
|
"@hanzogui/portal": "3.0.2",
|
|
"@hanzogui/remove-scroll": "3.0.2",
|
|
"@hanzogui/scroll-view": "3.0.2",
|
|
"@hanzogui/sheet": "3.0.2",
|
|
"@hanzogui/stacks": "3.0.2",
|
|
"@hanzogui/text": "3.0.2",
|
|
"@hanzogui/use-controllable-state": "3.0.2",
|
|
"@hanzogui/use-event": "3.0.2",
|
|
"@hanzogui/use-presence": "3.0.1",
|
|
"@hanzogui/web": "3.0.2",
|
|
"@hanzogui/z-index-stack": "3.0.2"
|
|
},
|
|
"patchedDependencies": {
|
|
"@luxfi/[email protected]": "patches/@[email protected]"
|
|
}
|
|
},
|
|
"packageManager": "[email protected]"
|
|
}
|