LocalNet Development
Documentation Index
Fetch the complete documentation index at: https://docs.canton.network/llms.txt Use this file to discover all available pages before exploring further.
LocalNet Development
Using cn-quickstart’s LocalNet as your primary development and testing environment
LocalNet is a Docker Compose-based local network that mirrors the Canton Network topology on your development machine. It gives you multiple validators, wallet services, PQS, and the full Splice applications — everything you need to build and test multi-party applications without connecting to a shared network.
What LocalNet Provides
LocalNet provides a 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 — Super validator, for providing the Global Synchronizer and handling automated market trading (AMT)
LocalNet is designed for development and testing. It is not intended for production use.
The Development Lifecycle
Most development teams go through five distinct phases with the cn-quickstart:
Learning phase (1-2 days)
Your first interaction with cn-quickstart focuses on getting the environment running, exploring the sample application, and understanding the architecture. Keep your local copy current by pulling from main:
git clone https://github.com/digital-asset/cn-quickstart.git
cd cn-quickstart
# Regular updates during learning
git pull origin main
Experimentation phase (1-2 weeks)
You begin modifying configurations, exploring APIs, and changing Daml code to test integration patterns. Set up upstream tracking so you can selectively incorporate changes:
git remote add upstream https://github.com/digital-asset/cn-quickstart.git
git checkout -b experiments
git fetch upstream
git merge upstream/main
Development phase (2-3 weeks)
You start building your own application alongside the sample. Many developers create their code in parallel directories:
cn-quickstart/
├── quickstart/ # Original sample code
│ ├── daml/
│ ├── backend/
│ └── frontend/
└── myapp/ # Your application code
├── daml/
├── backend/
└── frontend/
Update settings.gradle.kts to include both project structures. Use .envrc.private for local environment overrides. Create custom Docker Compose files that extend the cn-quickstart configuration.
Separation phase
Once your application’s complexity exceeds the cn-quickstart sample, remove the dependency on the original code. Delete the sample directories, update build files, and remove the upstream git remote:
git remote remove upstream
rm -rf quickstart/
# Update settings.gradle.kts, build.gradle.kts, etc.
Ongoing updates
After separation, periodically review cn-quickstart’s changelog for tooling improvements and updated tool versions you can adopt. The cn-quickstart becomes a reference rather than a dependency.
Starting and Stopping LocalNet
If you’re using cn-quickstart, the Makefile wraps the Docker Compose commands:
cd quickstart
make setup # First-time setup
make build # Build Daml and backend
make start # Start LocalNet
make stop # Stop LocalNet
For direct Docker Compose control, set the environment variables LOCALNET_DIR (path to the LocalNet directory) and IMAGE_TAG (Splice version), then use:
# Start all nodes
docker compose --env-file $LOCALNET_DIR/compose.env \
--env-file $LOCALNET_DIR/env/common.env \
-f $LOCALNET_DIR/compose.yaml \
-f $LOCALNET_DIR/resource-constraints.yaml \
--profile sv \
--profile app-provider \
--profile app-user up -d
# Stop all nodes
docker compose --env-file $LOCALNET_DIR/compose.env \
--env-file $LOCALNET_DIR/env/common.env \
-f $LOCALNET_DIR/compose.yaml \
-f $LOCALNET_DIR/resource-constraints.yaml \
--profile sv \
--profile app-provider \
--profile app-user down -v
You can use Docker Compose profiles (--profile app-provider, etc.) alongside environment variables (APP_PROVIDER_PROFILE=on/off) to disable specific validators and reduce resource usage.
Ports and Services
Ports follow a pattern based on the validator role:
- SV:
4${PORT_SUFFIX}(e.g., Ledger API at4901) - App Provider:
3${PORT_SUFFIX}(e.g., Ledger API at3901) - App User:
2${PORT_SUFFIX}(e.g., Ledger API at2901)
Key port suffixes:
901— Participant Ledger API (gRPC)902— Participant Admin API975— JSON API (HTTP)903— Validator Admin API900— Canton HTTP health check961— Canton gRPC health check
Web UIs:
- App User Wallet:
http://wallet.localhost:2000 - App Provider Wallet:
http://wallet.localhost:3000 - SV UI:
http://sv.localhost:4000 - Scan UI:
http://scan.localhost:4000
127.0.0.1 scan.localhost
127.0.0.1 wallet.localhost
127.0.0.1 sv.localhost
Debugging with LocalNet
Capturing and viewing logs
The fastest way to start debugging is to capture all logs at once:
make capture-logs
Use lnav to analyze the captured log files — it handles multiple log formats and lets you filter, search, and correlate events across services.
Viewing live logs
# All containers
docker compose -f $LOCALNET_DIR/compose.yaml logs -f
# Specific service
docker compose -f $LOCALNET_DIR/compose.yaml logs -f app-provider-participant
# Filter for errors
docker compose -f $LOCALNET_DIR/compose.yaml logs -f 2>&1 | grep -i error
Accessing the Canton Console
The Canton Console gives you direct access to inspect and modify the participant, sequencer, and mediator nodes:
docker compose --env-file $LOCALNET_DIR/compose.env \
--env-file $LOCALNET_DIR/env/common.env \
-f $LOCALNET_DIR/compose.yaml \
-f $LOCALNET_DIR/resource-constraints.yaml \
run --rm console
Or with cn-quickstart: make canton-console.
Common issues
- Containers fail to start — Check available memory. LocalNet with all three validators requires significant resources. Disable unused profiles to reduce the footprint.
- Scan UI shows no rounds — It may take several minutes after startup before data appears in the Scan UI. This is expected behavior during initial network bootstrapping.
- Database connection errors — The single PostgreSQL instance handles all components. Check that it started successfully before other services.
Next Steps
- Testing Strategies — Testing pyramid and approaches for Canton applications
- Deployment Progression — Moving from LocalNet to DevNet, TestNet, and MainNet
Mirrored from Canton Network official documentation (CC-BY-4.0) by CC Privacy Club for learning purposes.