NervaAPI is a RESTful API server for the Nerva blockchain. It provides a simple interface to interact with the Nerva blockchain using HTTP requests.
The repository is a monorepo: the Quart API lives in src/backend, and the documentation site — a Vue 3 + Tailwind CSS app built with Vite — lives in src/frontend.
- Git
- Python >= 3.10
- MongoDB database
uvpackage manager- Node.js >= 22 (for the documentation frontend)
- make (optional)
-
Clone the repository
git clone https://github.com/sn1f3rt/NervaAPI.git
-
Switch to the project directory
cd NervaAPI -
Create a virtual environment
uv venv
-
Install dependencies
uv sync --all-extras --no-dev # or make install
Copy the config.example.py file to src/backend/config.py and update the variables.
uv run hypercorn --reload --bind 127.0.0.1:8080 backend.launcher:app # or make runThe API server will be running at http://127.0.0.1:8080, reloading on changes.
uv run hypercorn --bind 0.0.0.0:17568 backend.launcher:app # or make run-prodThe API server will be running at http://localhost:17568. TLS is terminated by the reverse proxy in front of the app (see Deployment).
The documentation site is a Vue 3 + Tailwind CSS app located in src/frontend. It is a static API reference. The API is served under /v1 on the same origin, so the docs derive their base URL from the browser — there is nothing to configure. The JS tooling (package.json, Vite and TypeScript configs) lives at the repository root, alongside pyproject.toml.
-
Install the Node dependencies
npm install
-
Start the dev server — runs on
http://127.0.0.1:3000and proxies/v1to the backend on:8080npm run dev
To bring up the whole stack at once — the backend on
:8080and the docs on:3000— run:npm run serve
-
Build the static site for production (outputs to
dist/)npm run build
In production, nginx serves the built dist/ and reverse-proxies /v1 to the API — see Deployment.
The repository ships a Docker Compose stack that builds the documentation, serves it, and runs the API behind a single port. It is meant to sit behind an existing reverse proxy (e.g. HestiaCP) that terminates TLS for your domain. Two services:
- web — nginx serving the built docs and reverse-proxying everything under
/v1to the API. Published on127.0.0.1:17568. - api — the Quart app run with Hypercorn (internal only).
MongoDB (Atlas) and the Nerva daemon are external, so they are configured, not containerised.
-
Create the backend config (kept out of the image and mounted at runtime):
cp src/backend/config.example.py src/backend/config.py
Set
MONGODB_URI(your Atlas URI),DAEMON_RPC_HOST/DAEMON_RPC_PORTandCORS_ALLOW_ORIGIN. If the daemon runs on the same host as the stack, useDAEMON_RPC_HOST = "host.docker.internal"— theapiservice is preconfigured (extra_hosts: host-gateway) to reach the host; for a remote daemon, point it at that server's address. Either way, the host firewall must allow the connection — if you closed the daemon's RPC port to the public, make sure the Docker bridge subnet (e.g.172.16.0.0/12) can still reach it. -
Build and start (detached):
docker compose up -d --build
restart: unless-stoppedkeeps the stack running across reboots — ensure the Docker service itself starts on boot (systemctl enable docker).
The site is then reachable at http://127.0.0.1:17568: the docs at /, the API at /v1/....
Ready-made web templates are provided in docker/hestia. They proxy the domain to the stack over plain HTTP (TLS stays at HestiaCP's edge — no certificates are needed inside the stack) and forward the real client IP, which the API needs for rate limiting and analytics.
-
Copy them into HestiaCP's nginx web template directory:
cp docker/hestia/nerva_api.tpl docker/hestia/nerva_api.stpl /usr/local/hestia/data/templates/web/nginx/
-
For the domain, set the Web Template to
nerva_apiand enable SSL (Let's Encrypt). -
Rebuild the domain and reload nginx:
v-rebuild-web-domain <user> <domain> nginx -t && systemctl reload nginx
NervaAPI is free and public, but its development and hosting are not. If you find it useful, please consider supporting its upkeep:
- Nerva (XNV):
NV1PqtQwRik7FFeAJ5n7iKbHtve3nkeM99x3Q31wjBAm7twvRv6NYkbbP7vSG3n8N3fsUh2gpfZG2PRi4gYhxL4h2r2SnhUoX - Monero (XMR):
48SSQzEcvQPK7H69vUvwReFT7tCDESdRhPFGubTgJ8WeXUUPQRWjY8oZk3wHfLhsUnChJ1BYyYfoLKQh8epYsupAAWCnDKh - Bitcoin (BTC):
bc1qzg4jjtxq6cg22pmlaesyva64nrjzcaqud968vf - Ethereum (ETH):
0x97173e82df1d9Cc76946241D63A9f9231Dea1566
Prefer fiat? You can also support via GitHub Sponsors, Patreon, or Buy Me a Coffee.
Copyright © 2024-present Sayan "sn1f3rt" Bhattacharyya, The Nerva Project