Modern Phantasma Explorer frontend (Next.js). This README covers local development and deployment details.
Requirements:
- Node.js + npm.
- Optional:
justfor task shortcuts.
npm install
npm run devCommon tasks:
npm run build(production build)npm run start(serve production build)npm run lintnpm run test(Playwright e2e)npm run test:unit(Vitest unit)
If you use just, see the Justfile section below.
The app loads runtime config from /public/config.json at runtime.
- The repo ships a local default in
public/config.jsonfor convenience. - For deployments, mount the config file into the container at
/app/public/config.jsoninstead of baking environment-specific values into the image.
Example:
{
"nexus": "mainnet",
"apiBaseUrl": "http://localhost:8000/api/v1",
"rpcBaseUrl": "http://localhost:5172/api/v1",
"explorers": {
"mainnet": "http://localhost:3000",
"testnet": "https://testnet-explorer.phantasma.info",
"devnet": "https://devnet-explorer.phantasma.info"
},
"buildStamp": {
"enabled": true,
"label": "local"
},
"diagnostics": {
"enabled": true
}
}Config fields:
nexus:mainnet | testnet | devnet(drives network switcher + links)apiBaseUrl: explorer API base URL (include/api/v1)rpcBaseUrl: RPC REST base URL for "View RPC API" links (optional override)explorers: per-network explorer URLsbuildStamp.enabled: show/hide build badgebuildStamp.label: label shown in footer (badge is shown only when enabled and the label is non-empty)diagnostics.enabled: console diagnostics toggle
Notes:
buildStamp.timeandbuildStamp.hashare not read from config; they are injected at build time.- If
rpcBaseUrlis omitted, the app uses built-in defaults from code:- mainnet:
https://pharpc1.phantasma.info/api/v1 - testnet:
https://testnet.phantasma.info/api/v1 - devnet:
https://devnet.phantasma.info/api/v1If you want a different RPC endpoint (includingpharpc2), setrpcBaseUrlexplicitly.
- mainnet:
This project always embeds a build stamp (UTC time + short git hash) at build time. It is the authoritative way to verify the exact build running in a container.
How it works:
scripts/generate-build-info.mjswritessrc/lib/build-info.tson every build.npm run buildtriggersprebuild, so the stamp is automatic.build-info.tsis committed so imports resolve, but its contents are overwritten per build.
Important rules:
- Never put
buildStamp.timeorbuildStamp.hashinpublic/config.json. - Docker Compose requires
BUILD_GIT_SHA(the compose file enforces it). If you are building without Compose, the script can derive the hash from.git.
/version is always available (even when the build stamp is hidden) and shows:
- build time
- git hash
- runtime config values (nexus / apiBaseUrl / diagnostics)
The footer build-stamp badge links to /version only when enabled and labeled.
Use the files in docker/ for builds and runs. Copy them into your deployment
stack directory before deploying.
Deployment rules:
- Sync
docker/from this repo into the deployment stack directory (outside the repo). Use the stack's sync script if provided. - Provide a runtime config file and mount it to
/app/public/config.json. - Provide
EXPLORER_PORTandEXPLORER_CONFIG_PATHvia env or.env. - Build + run with Docker or Podman.
- Verify
/versionshows the new build time + hash.
Required env:
EXPLORER_PORT(host port to bind to container3000)EXPLORER_CONFIG_PATH(absolute path to runtime config file)EXPLORER_BUILD_CONTEXT(optional; defaults to repo root)EXPLORER_DOCKERFILE(optional; defaults todocker/Dockerfile)
Example (conceptual):
BUILD_GIT_SHA=$(git rev-parse --short HEAD)
docker compose -f docker/docker-compose.yml up -d --build --force-recreateRPC links:
If you don't set rpcBaseUrl, the app uses built-in defaults per network
(pharpc1.phantasma.info, testnet.phantasma.info, devnet.phantasma.info).
Override only when you need a custom RPC endpoint (for example, a local chain).
Use this list every time you deploy:
- Ensure the deployment stack uses the latest
docker/files from this repo. - Verify
EXPLORER_CONFIG_PATHpoints to the intended config file. - Verify
EXPLORER_PORTis correct and free. - Build and restart the container.
- Open
/versionand confirm the build time + hash match this repo. - Smoke-test a block page, transaction page, and
/version.
Mainnet (example):
{
"nexus": "mainnet",
"apiBaseUrl": "https://api-explorer.phantasma.info/api/v1",
"rpcBaseUrl": "https://pharpc1.phantasma.info/api/v1",
"explorers": {
"mainnet": "https://explorer.phantasma.info",
"testnet": "https://testnet-explorer.phantasma.info",
"devnet": "https://devnet-explorer.phantasma.info"
},
"buildStamp": { "enabled": true, "label": "mainnet" },
"diagnostics": { "enabled": false }
}Testnet (example):
{
"nexus": "testnet",
"apiBaseUrl": "https://api-testnet-explorer.phantasma.info/api/v1",
"rpcBaseUrl": "https://testnet.phantasma.info/api/v1",
"explorers": {
"mainnet": "https://explorer.phantasma.info",
"testnet": "https://testnet-explorer.phantasma.info",
"devnet": "https://devnet-explorer.phantasma.info"
},
"buildStamp": { "enabled": true, "label": "testnet" },
"diagnostics": { "enabled": false }
}Devnet (example):
{
"nexus": "devnet",
"apiBaseUrl": "https://api-devnet-explorer.phantasma.info/api/v1",
"rpcBaseUrl": "https://devnet.phantasma.info/api/v1",
"explorers": {
"mainnet": "https://explorer.phantasma.info",
"testnet": "https://testnet-explorer.phantasma.info",
"devnet": "https://devnet-explorer.phantasma.info"
},
"buildStamp": { "enabled": true, "label": "devnet" },
"diagnostics": { "enabled": true }
}Local chain (example):
{
"nexus": "mainnet",
"apiBaseUrl": "http://localhost:8000/api/v1",
"rpcBaseUrl": "http://localhost:5172/api/v1",
"explorers": {
"mainnet": "http://localhost:3000",
"testnet": "https://testnet-explorer.phantasma.info",
"devnet": "https://devnet-explorer.phantasma.info"
},
"buildStamp": { "enabled": true, "label": "local" },
"diagnostics": { "enabled": true }
}This repo ships with a justfile to standardize common tasks.
List tasks:
justCommon targets:
just install,just build,just devjust lint,just test,just test-unit,just test-e2ejust docker-up,just docker-down,just docker-logsjust podman-up,just podman-down,just podman-logs
docker-up / podman-up automatically inject BUILD_GIT_SHA from the current git HEAD.
Quick alias:
just ris an alias forjust dev.
npm run test(Playwright end-to-end)npm run test:unit(Vitest unit tests)
- Build fails with "Set BUILD_GIT_SHA": use
just docker-upor setBUILD_GIT_SHA=$(git rev-parse --short HEAD)before running Compose. - Config not applied: confirm the container mounts
/app/public/config.jsonand that the file contents match the intended network/API. - Wrong network links: check
nexusandexplorersvalues in config. - No build stamp: ensure
npm run buildwas used andprebuildran.