Skip to main content
The Sundial-Layer-Node is the production TypeScript node that processes L2 transactions and commits block headers to Cardano. It handles everything from receiving raw transactions over HTTP and validating them against the mempool, to batching them into blocks and submitting signed block-header commitments to the Cardano L1 state queue. You can run the node as a single all-in-one process (the default) or deploy each role in its own container for horizontal scaling and fault isolation.

Node Roles

The node ships with four logical roles. You select a role by setting NODE_ROLE in your environment. In production you can deploy each role as a separate container sharing the same PostgreSQL and Redis infrastructure.

api

HTTP ingress layer. Receives L2 transactions via REST, validates the CBOR envelope, and enqueues payloads to a Redis Stream for downstream processing.

tx-processor

Consumes the Redis Stream, deserializes each transaction, computes its hash, and inserts it into the mempool database. Scales horizontally — run multiple instances of this role against the same stream.

sequencer

Builds blocks from the mempool, commits block headers to the Cardano L1 state queue, and runs the L1 user-event sync fiber to pick up deposits and withdrawals.

all

Runs all three roles in a single process. This is the default and is recommended for getting started or running a single-node testnet setup.
Set NODE_ROLE=all in your .env file to run everything in one container. Switch to the split Docker Compose profile to deploy api, tx-processor, and sequencer as separate services.

Prerequisites

Before deploying the Sundial-Layer-Node, make sure you have the following ready:
  • Docker and Docker Compose (v2.20+)
  • PostgreSQL 15 — the Docker Compose stack includes a bundled instance
  • Redis 7+ — also bundled in the Docker Compose stack
  • Cardano L1 provider — either a Blockfrost API key (quickest to set up) or a local Kupo + Ogmios endpoint pair (recommended for production)
  • Operator seed phrases — three separate 24-word seed phrases for the main operator wallet, the block-commitment wallet, and the merge-transaction wallet

Quick Start with Docker Compose

The fastest way to run a node is with the bundled Docker Compose stack, which starts the node alongside PostgreSQL, Redis, and the full observability suite.
1

Clone the repository

2

Create your environment file

Copy the example environment file and open it for editing:
At minimum, set your L1 provider credentials and operator seed phrases. For a Blockfrost-backed testnet node:
Use three distinct seed phrases — one per variable. Never reuse the same seed phrase across roles, and never reuse any of these as a faucet wallet seed.
3

Start all services

Launch the full stack (node + PostgreSQL + Redis + observability) using the monolith profile:
To start only the node and its database dependencies without monitoring:
4

Verify the node is running

Confirm all containers started successfully:
Then probe the node’s health and API endpoints:
Follow the node logs in real time:

Smoke Checks

Run these checks after startup to confirm the full stack is healthy.
1

Confirm the node is live and ready

Once the node is ready, confirm the API is serving requests:
A JSON response with state-queue data confirms the node is fully operational.
2

Confirm Prometheus is scraping

The response should list active scrape jobs for prometheus, midgard_nodes, cadvisor, and tempo.
3

Confirm metrics are flowing

Open Grafana at http://localhost:3001 and verify the provisioned data sources — prometheus, Loki, and Tempo — are all shown as connected.

Observability Stack

When you start the node with the monolith Docker Compose profile, the --with-monitoring flag is passed automatically. This activates the Prometheus metrics exporter on PROM_METRICS_PORT and the OpenTelemetry trace exporter pointed at Tempo. The node exposes these tracked metrics:
Generate some traffic by submitting transactions through POST /submit, then open Grafana Explore to verify logs appear in Loki and traces appear in Tempo. This confirms the full telemetry pipeline is working end to end.

Stopping and Cleaning Up

Running docker compose down -v deletes all PostgreSQL, Prometheus, Grafana, and Tempo volumes. Only do this when you want a clean slate, not as part of routine restarts.

Split-Role Deployment

For production operators who want to scale transaction processing independently from block production, use the split Docker Compose profile. This starts node-api, node-tx-processor, and node-sequencer as separate containers, all sharing the same PostgreSQL and Redis backend.
Each role container reads NODE_ROLE from the environment override in the Compose file. You can run multiple node-tx-processor replicas to increase mempool ingestion throughput — they compete for work from the same Redis Stream consumer group.

Nix Deployment

If you prefer a reproducible Nix-based build, clone the standalone node repository and build from the tagged release:

Troubleshooting

Verify that demo/midgard-node/.env exists and all required variables are populated. Run grep -E '^(L1_PROVIDER|NETWORK|L1_OPERATOR_SEED_PHRASE)' .env to confirm the essentials are set.
Confirm you started with the monolith profile (not docker-compose.dev.yaml). Check that PROM_METRICS_PORT=9464 is set in your .env and that the node started with --with-monitoring in its command.
Verify Promtail is running and has access to /var/run/docker.sock and /var/lib/docker/containers. Confirm the node container has the logging: promtail label in the Compose file.
Check that OLTP_EXPORTER_URL=http://tempo:4318/v1/traces is set in your .env. The variable name is OLTP_EXPORTER_URL (not OTLP) — this is by design in the current implementation.
The stack uses ports 3000, 3001, 3100, 3200, 4317, 4318, 5433, 6379, 8080, 9090, and 9464. Stop any existing services on those ports, or override them in .env using the _HOST_PORT variable variants.
Run docker compose down -v to clear the Loki volume, then restart with docker compose --profile monolith up -d --build.

Hardware Requirements

For reliable block production on mainnet, run the node on hardware that meets or exceeds these specifications: The AWS equivalent for the recommended configuration is an m6i.2xlarge instance (8 vCPU, 32 GB RAM).

Next Steps

Configuration Reference

Complete reference for all environment variables — L1 provider, timing intervals, PostgreSQL, Redis, and monitoring settings.

CLI Reference

Use the midgard CLI to manage wallets, send transactions, and check node status from the command line.