- Overview
- Tutorials
- Getting started
- Get started with Canton and the JSON Ledger API
- Get Started with Canton, the JSON Ledger API, and TypeScript
- Get started with Canton Network App Dev Quickstart
- Using the JSON Ledger API
- Get started with smart contract development
- Basic contracts
- Test templates using Daml scripts
- Build the Daml Archive (.dar) file
- Data types
- Transform contracts using choices
- Add constraints to a contract
- Parties and authority
- Compose choices
- Handle exceptions
- Work with dependencies
- Functional programming 101
- The Daml standard library
- Test Daml contracts
- Next steps
- Application development
- Getting started
- Development how-tos
- Component how-tos
- Explanations
- References
- Application development
- Smart contract development
- Daml language cheat sheet
- Daml language reference
- Overview: Template Structure
- Reference: Templates
- Reference: Choices
- Reference: Updates
- Reference: Data Types
- Reference: Built-in Functions
- Reference: Expressions
- Reference: Functions
- Reference: Daml File Structure
- Reference: Daml Packages
- Reference: Contract Keys
- Reference: Interfaces
- Reference: Exceptions (Deprecated)
- Daml standard library
- DA.Action.State.Class
- DA.Action.State
- DA.Action
- DA.Assert
- DA.Bifunctor
- DA.Crypto.Text
- DA.Date
- DA.Either
- DA.Exception
- DA.Fail
- DA.Foldable
- DA.Functor
- DA.Internal.Interface.AnyView.Types
- DA.Internal.Interface.AnyView
- DA.List.BuiltinOrder
- DA.List.Total
- DA.List
- DA.Logic
- DA.Map
- DA.Math
- DA.Monoid
- DA.NonEmpty.Types
- DA.NonEmpty
- DA.Numeric
- DA.Optional
- DA.Record
- DA.Semigroup
- DA.Set
- DA.Stack
- DA.Text
- DA.TextMap
- DA.Time
- DA.Traversable
- DA.Tuple
- DA.Validation
- GHC.Show.Text
- GHC.Tuple.Check
- Prelude
- Daml Script
- Smart contract upgrading reference
- Glossary of concepts
Canton Network quickstart project structure¶
Overview¶
The CN Quickstart provides a complete development environment for building Canton Network applications. It combines build tools (Gradle, Make), deployment infrastructure (Docker Compose), and a reference application to accelerate your development.
The project demonstrates Canton development patterns through a licensing application while providing the scaffolding you need for your own applications.
Reference application¶
The Quickstart includes a licensing application with four parties:
Application Provider - Sells licenses
Application User - Buys licenses
DSO Party - Operates the payment system (Super Validators in CN)
Amulet - Token system for payments (Canton Coin by default)
The Provider and User are independent parties, each requiring their own validator node to maintain separate ledger state. They coordinate through the Super Validator. Payments require Canton Wallet integration and Splice dependencies.
This four-party model shapes the project. The Splice container runs all three validators with configs in docker/modules/localnet/conf/splice/ (app-provider/, app-user/, sv/), provider and user application modules in backend/ and frontend/, payment contracts in daml/, and Splice DARs in daml/dars/.
Work through the Explore the Canton Network Application Quickstart demo guide for the complete workflow walkthrough.
Development environment (Nix + Direnv)¶
The repository uses Nix and Direnv to provide consistent, cross-platform development dependencies including JDK, Node.js, and TypeScript.
If you prefer not to use Nix, you can work directly in quickstart/ but will need to manage dependencies manually.
Review the Canton Utility Setup if you require utility deployment support.
Key files:
.envrc- Activates Nix environment via Direnvnix/shell.nix- Defines development dependenciesnix/sources.json- Pins Nix release for reproducible buildsquickstart/- The main project directory
Quickstart directory structure¶
The quickstart/ files and directories fall into one of three categories:
Build Configuration
- Makefile # Project orchestration
- build.gradle.kts # Root build configuration
- buildSrc/ # Custom Gradle plugins
- gradle/ # Gradle wrapper files
- gradlew # Gradle wrapper (Unix)
- gradlew.bat # Gradle wrapper (Windows)
- settings.gradle.kts # Project structure definition
Deployment Configuration
- .env # Environment variables
- compose.yaml # Docker Compose configuration
- config/ # Service configurations
- docker/ # Docker image definitions
Application Source
- daml/ # Smart contracts
- backend/ # Java backend services
- frontend/ # React frontend
- common/ # Shared API definitions
Build system¶
Gradle¶
Gradle builds the Java backend and Daml contracts. The backend uses Transcode-generated classes from DAR files to interact with the Ledger API.
Custom Gradle plugins (buildSrc/src/main/kotlin/):
Plugin |
Purpose |
|---|---|
|
Interactive generation of |
|
Propagates |
|
Unpacks |
|
Reads |
Make¶
Make provides a command-line interface to build tools and Docker Compose.
Run make help to see available commands.
Common targets:
make setup- Configure deployment profilemake build- Build all componentsmake start- Start the applicationmake status- Show running containersmake stop- Stop the application
The Makefile serves as both executable commands and documentation of the development workflow.
Deployment configuration¶
Docker Compose¶
Docker Compose orchestrates the local development environment, LocalNet, which simulates a Canton Network on your laptop. It includes validator nodes, a super validator, Canton Coin wallet, and supporting services.
Key files:
compose.yaml- Main Docker Compose configuration.env- Environment variables for all servicesconfig/- Service-specific configuration filesdocker/- Docker image build contexts
Port mapping¶
LocalNet uses a prefix-suffix pattern for port numbers:
Prefixes:
2xxx- Application User validator3xxx- Application Provider validator4xxx- Super Validator
Common Suffixes:
x901- Ledger APIx902- Admin APIx903- Validator APIx975- JSON API5432- PostgreSQL
Examples
Application User Ledger API:
2901Provider Validator API:
3903Application User JSON API:
2975.
Port mapping security¶
Port mappings for LocalNet expose the AdminAPI and Postgres ports, which is a security risk on a public network.
However, it’s useful to have direct access to these ports when developing and testing locally.
Do NOT expose these ports when preparing configurations for non-local deployments.
You can remove ports in their appropriate Docker file.
Health checks¶
Health check endpoints for each validator are in ..docker/splice/health-check.sh.
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
Empty responses indicate healthy services.
Admin ports are defined in quickstart/docker/modules/localnet/compose.yaml
curl -v http://localhost:2902/admin # Accesses App User admin if exposed
curl -v http://localhost:3902/admin # Accesses App Provider admin if exposed
See Using the JSON Ledger API for detailed port usage and authentication patterns.
Application structure¶
Canton applications have three layers:
User Interface (frontend/) - React web application
Local Business Logic (backend/) - Java services, PQS queries, integrations
Consensus Business Logic (daml/) - Smart contracts requiring multi-party agreement
The Quickstart uses a fully mediated architecture where the backend handles all ledger interactions. Alternatively, you could use a CQRS architecture where the frontend submits commands directly to the ledger and designate the backend to handle queries.
Daml smart contracts¶
The licensing application demonstrates multi-party workflows requiring consensus between the app provider, user, and DSO (for payments).
licensing/
└── daml/
└── Licensing/
├── AppInstall.daml # User onboarding
├── License.daml # License management
└── Util.daml # Helper functions
Core business flow¶
The consensus layer handles multi-party agreements through these Daml templates:
User Onboarding (AppInstall.daml):
AppInstallRequest- User initiates installation using the Propose/Accept patternChoices:
AppInstallRequest_Accept,AppInstallRequest_Reject,AppInstallRequest_Cancel
AppInstall- Active installation relationship between provider and userChoice:
AppInstall_CreateLicense- Provider creates licenses for the user
License Management (License.daml):
License- Time-based access control with expiration dateChoice:
License_Renew- CreatesAppPaymentRequest(Splice Wallet) andLicenseRenewalRequestChoice:
License_Expire- Archives expired licenses
LicenseRenewalRequest- Handles license extensions through Canton Coin payments
Why consensus layer?¶
These operations require consensus because they involve agreements between multiple parties, making them unsuitable for local backend services.
User creates
AppInstallRequest→ Provider must see and respondProvider exercises
AppInstallRequest_Accept→ Both parties must agree to createAppInstallProvider creates
Licensecontracts → User must accept termsLicense renewal → Requires payment validation across user, provider, and DSO’s payment system
Backend services¶
The backend is a Spring Boot application that mediates ALL ledger interactions using two distinct paths:
Queries → PQS (Participant Query Store) for fast read access to ledger state
Commands → Ledger API GRPC for exercising choices and creating contracts
This fully mediated architecture centralizes authentication and ledger access, keeping the frontend simple.
Module structure (backend/src/main/java/com/digitalasset/quickstart/):
Module |
Purpose |
Key Components |
|---|---|---|
|
OAuth2 authentication and access control |
Bearer token validation |
|
OpenAPI endpoint implementations |
Combines PQS queries with Ledger API commands |
|
Ledger API GRPC client |
|
|
Business-logic PQS queries |
|
|
Low-level PQS access |
|
|
Codegen and JSON utilities |
|
|
Spring Boot configuration |
|
Backend architecture pattern¶
The backend provides two types of HTTP endpoints:
GET - Query contracts and their state (via PQS)
POST - Execute choices on contracts (via Ledger API, with contract IDs in URLs)
The backend uses Transcode-generated Java classes from DAR files to provide type-safe ledger interactions.
Rebuild the backend with make build to regenerate these classes after updating Daml contracts.
Frontend application architecture¶
The frontend is a React application written in TypeScript using Vite for builds and Axios for HTTP transport.
The backend handles ALL ledger interactions. The frontend never talks directly to Canton or the Ledger API. This approach:
Centralizes authentication and access control in one place
Allows the frontend to integrate non-ledger data sources easily
Uses OpenAPI schemas as data models (DTOs) between frontend and backend
HTTP client: Axios with OpenAPI client generation
Some Canton applications use CQRS architecture where the frontend submits commands directly to the Ledger API using Daml-generated TypeScript. This tighter coupling works well for Daml-centric applications but requires the frontend to understand Canton concepts like party IDs and contract IDs.
Common API definition¶
common/openapi.yaml defines the HTTP interface between frontend and backend.
The API uses:
GET
/api/resource- Query contracts and state (via PQS)POST
/api/contracts/{contractId}/exercise- Execute choices (via Ledger API)
The OpenAPI schema generates TypeScript types for the frontend and validates requests in the backend.
Configuration reference¶
Environment variables¶
The .env file contains version numbers, feature flags, and default configurations.
Use .env.local for local overrides (not tracked in git).
Docker Compose modules¶
LocalNet is built from modular Docker Compose layers:
Base LocalNet infrastructure (from Splice)
Authentication (Keycloak)
Observability (Grafana, Prometheus, Loki)
PQS (Participant Query Store)
Application services
Development workflow¶
Quick Start¶
cd quickstart/
make setup # Configure deployment
make build # Build all components
make start # Start LocalNet
make status # Verify containers running
Iterative development¶
make build-daml # Rebuild Daml contracts
make build-backend # Rebuild Java services
make build-frontend # Rebuild React app
make restart # Restart services with new code
Debugging and logs¶
make capture-logs # Start log capture (separate terminal)
make shell # Open Daml Shell for ledger queries
See Debugging and troubleshooting with lnav for log analysis techniques.
Next steps¶
Once you understand the project structure, visit the TL;DR for new Canton Network developers for additional guides to explore.