> ## Documentation Index
> Fetch the complete documentation index at: https://cantonfoundation-feature-integrate-google-analytics.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# LocalNet

> Run a multi-validator Canton Network locally with Docker Compose for development and integration testing.

LocalNet provides a straightforward topology comprising three participants, three validators, a PostgreSQL database, and several web applications (wallet, sv, scan) behind an NGINX gateway. Each validator plays a distinct role within the Splice ecosystem:

* **app-provider**: for the user operating their application
* **app-user**: for a user wanting to use the app from the App Provider
* **sv**: for providing the Global Synchronizer and handling AMT

Designed primarily for development and testing, LocalNet is not intended for production use.

LocalNet is provided as part of the [cn-quickstart](https://github.com/digital-asset/cn-quickstart) repository.

## What LocalNet Provides

* Three validators: Super Validator (SV), App Provider, and App User
* A local synchronizer with sequencer and mediator
* Canton Coin wallet services for each validator
* PQS (Participant Query Store) instances
* JSON API endpoints
* Keycloak for authentication (optional)
* Observability stack: Grafana, Prometheus, Loki (optional)

## Setup

From the cn-quickstart repository:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
git clone https://github.com/digital-asset/cn-quickstart
cd cn-quickstart
direnv allow
cd quickstart
make install-daml-sdk
make setup
make build
make start
```

`make setup` prompts you to select a deployment profile and generates the appropriate `.env.local` configuration. `make build` compiles the Daml contracts, Java backend, and React frontend. `make start` launches the Docker Compose stack.

Check the status of running containers:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
make status
```

Stop the environment:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
make stop
```

## Network Topology

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TB
    subgraph LocalNet
        SV[Super Validator<br>Port prefix: 4xxx]
        PROV[App Provider<br>Port prefix: 3xxx]
        USER[App User<br>Port prefix: 2xxx]
        SEQ[Sequencer]
        MED[Mediator]
    end

    SV --> SEQ
    PROV --> SEQ
    USER --> SEQ
    SEQ --> MED
```

Each validator runs a participant, wallet services, and supporting infrastructure. The Super Validator also runs the synchronizer components (sequencer and mediator) and the Splice SV app.

## Port Conventions

## Exposed Ports

The following section details the ports used by various services. The default database port is **DB\_PORT=5432**.

Other ports are generated using specific patterns based on the validator:

* For the Super Validator (sv), the port is specified as `4${PORT_SUFFIX}`.
* For the App Provider, the port is specified as `3${PORT_SUFFIX}`.
* For the App User, the port is specified as `2${PORT_SUFFIX}`.

These patterns apply to the following ports suffixes:

* **PARTICIPANT\_LEDGER\_API\_PORT\_SUFFIX**: 901
* **PARTICIPANT\_ADMIN\_API\_PORT\_SUFFIX**: 902
* **PARTICIPANT\_JSON\_API\_PORT\_SUFFIX**: 975
* **VALIDATOR\_ADMIN\_API\_PORT\_SUFFIX**: 903
* **CANTON\_HTTP\_HEALTHCHECK\_PORT\_SUFFIX**: 900
* **CANTON\_GRPC\_HEALTHCHECK\_PORT\_SUFFIX**: 961

UI Ports are defined as follows:

* **APP\_USER\_UI\_PORT**: 2000
* **APP\_PROVIDER\_UI\_PORT**: 3000
* **SV\_UI\_PORT**: 4000

## Application UIs

* **App User Wallet UI**

  > * **URL**: `http://wallet.localhost:2000`
  > * **Description**: Interface for managing user wallets.

* **App Provider Wallet UI**

  > * **URL**: `http://wallet.localhost:3000`
  > * **Description**: Interface for managing user wallets.

* **Super Validator Web UI**

  > * **URL**: `http://sv.localhost:4000`
  > * **Description**: Interface for super validator functionalities.

* **Scan Web UI**

  > * **URL**: `http://scan.localhost:4000`
  > * **Description**: Interface to monitor transactions.

<Note>
  <span class="title-ref">LocalNet</span> rounds may take up to 6 rounds (equivalent to one hour) to display in the scan UI.
</Note>

In most scenarios, the `*.localhost` domains (e.g., `http://scan.localhost`) will resolve to your local host IP `127.0.0.1`. There are some situations where the resolution does not occur and the solution is to add entries to your `/etc/hosts` file. For example, to resolve `http://scan.localhost` and `http://wallet.localhost` add these entry to the file:

```
   127.0.0.1   scan.localhost
   127.0.0.1   wallet.localhost


```

## Default Wallet Users

* **App User**: app-user
* **App Provider**: app-provider
* **SV**: sv

For example, the App User's Ledger API is at `localhost:2901`, and the App Provider's JSON API is at `localhost:3975`.

<Warning>
  The Admin API and PostgreSQL ports are exposed for development convenience. Do not expose these ports in non-local deployments.
</Warning>

## Configuration Options

### Deployment Profiles

`make setup` offers deployment profiles that control which optional services are included:

* **Minimal** -- Core validators and synchronizer only
* **Standard** -- Adds PQS, JSON API, and authentication
* **Full** -- Adds observability (Grafana, Prometheus, Loki)

### Environment Variables

The `.env` file in the `quickstart/` directory contains version numbers, feature flags, and service configuration. Create a `.env.local` file (not tracked by git) to override settings locally.

### Docker Compose Modules

LocalNet is built from modular Docker Compose layers in `docker/modules/`:

* `localnet/` -- Base infrastructure (validators, synchronizer)
* `auth/` -- Keycloak authentication
* `observability/` -- Grafana, Prometheus, Loki
* `pqs/` -- Participant Query Store instances
* `app/` -- Application services (backend, frontend)

## Health Checks

Verify that validators are healthy:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -f http://localhost:2903/api/validator/readyz  # App User
curl -f http://localhost:3903/api/validator/readyz  # App Provider
curl -f http://localhost:4903/api/validator/readyz  # Super Validator
```

An empty response indicates a healthy service.

## When to Use LocalNet vs Sandbox

**Use LocalNet** when you need to test:

* Multi-party workflows across separate validators
* Canton Coin transfers and traffic purchases
* Wallet integration
* Splice API interactions (Scan, Validator APIs)
* End-to-end flows with backend, frontend, and ledger

**Use the [Sandbox](/sdks-tools/development-tools/sandbox)** when you need:

* Fast iteration on contract logic
* Single-participant testing without Docker
* A lightweight environment for `dpm test` and Ledger API integration

## Related Pages

* [cn-quickstart](/sdks-tools/reference-projects/cn-quickstart) -- Repository overview and project structure
* [Sandbox](/sdks-tools/development-tools/sandbox) -- Lightweight single-node alternative
* [QuickStart walkthrough](/appdev/quickstart/running-the-demo) -- Step-by-step guide to running the demo application
