Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e864682
build: add BACKEND selector with dual-backend Make/Compose/Docker plu…
fernandomg Apr 29, 2026
3894a4b
feat(backend-js): bootstrap Fastify server with config and tooling
fernandomg Apr 29, 2026
f72ef70
feat(backend-js): auth subsystem with OAuth2, shared-secret, and tenants
fernandomg Apr 29, 2026
16ca2dc
feat(backend-js): PQS database layer and licensing repository
fernandomg Apr 29, 2026
cd7c33e
feat(backend-js): Canton JSON Ledger API client with typed Daml comma…
fernandomg Apr 29, 2026
8787038
feat(backend-js): licensing service and HTTP routes
fernandomg Apr 29, 2026
7a6aa24
docs: document the Node.js backend in the README
fernandomg Apr 29, 2026
143dd9e
fix: distinguish 404 from 500 on DELETE /admin/tenant-registrations
fernandomg Apr 29, 2026
3f710f1
build(deps): bump idna from 3.11 to 3.15 in /sdk (#353)
dependabot[bot] May 20, 2026
00ca1c7
build(deps): bump pip from 26.0.1 to 26.1 in /sdk (#348)
dependabot[bot] May 20, 2026
c5cd25e
build(deps): bump urllib3 from 2.6.3 to 2.7.0 in /sdk (#351)
dependabot[bot] May 20, 2026
5327209
build(deps): bump axios from 1.15.0 to 1.16.1 in /quickstart/frontend…
dependabot[bot] May 20, 2026
4955c9f
Merge branch 'main' into js-parity
fernandomg Jun 2, 2026
f457eaf
build(deps): bump react-router and react-router-dom (#355)
dependabot[bot] Jun 25, 2026
561bcb7
build(deps): bump starlette from 1.0.0 to 1.3.1 in /sdk (#359)
dependabot[bot] Jun 25, 2026
c6bfd69
build(deps): bump form-data from 4.0.5 to 4.0.6 in /quickstart/fronte…
dependabot[bot] Jun 29, 2026
1e50be0
build(deps-dev): bump @babel/core in /quickstart/frontend (#361)
dependabot[bot] Jun 29, 2026
c5db1c7
Make sure Quick Start works with 3.5 #33098 (#354)
Viktor-Kalashnykov-da Jun 30, 2026
47c5cde
Update docs links (#362)
dasormeter Jul 1, 2026
2f4edfc
update to sdk bundle 3.5.2 (#363)
dasormeter Jul 4, 2026
1800738
Merge branch 'main' into js-parity
fernandomg Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ gradle-app.setting
.direnv/

logs

# Prevent accidental npm installs at the repo root
/node_modules/
/package.json
/package-lock.json
55 changes: 42 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ The CN Quickstart is a rapidly evolving work in progress.
## Docs and guides

You can find Quickstart documentation in the Canton Network documentation portal.
- [Quickstart Installation](https://docs.digitalasset.com/build/3.3/quickstart/download/cnqs-installation.html)
- [Exploring The Demo](https://docs.digitalasset.com/build/3.3/quickstart/operate/explore-the-demo.html)
- [Project Structure](https://docs.digitalasset.com/build/3.3/quickstart/configure/project-structure-overview.html)
- [FAQ](https://docs.digitalasset.com/build/3.3/quickstart/troubleshoot/cnqs-faq.html)
- [Observability and Troubleshooting Overview](https://docs.digitalasset.com/build/3.3/quickstart/observe/observability-troubleshooting-overview.html)

- [Quickstart Installation](https://docs.canton.network/appdev/quickstart/prerequisites)
- [Exploring The Demo](https://docs.canton.network/appdev/quickstart/running-the-demo)
- [FAQ](https://docs.canton.network/appdev/faq)
- [Observability and Troubleshooting Overview](https://docs.canton.network/appdev/quickstart/observability-and-tracing#observability-and-tracing)
- [Quickstart Reference](https://docs.canton.network/sdks-tools/reference-projects/cn-quickstart#cn-quickstart)

### Technical documentation

Expand All @@ -36,7 +37,7 @@ This project is rapidly enhanced, so please check back often for updates.

## Setup

See the [Quickstart Installation Guide](https://docs.digitalasset.com/build/3.3/quickstart/download/cnqs-installation.html) for installation and setup directions.
See the [Quickstart Installation Guide](https://docs.canton.network/appdev/quickstart/index) for installation and setup directions.

## Quickstart

Expand Down Expand Up @@ -64,17 +65,41 @@ $ make shell
```

An assistant helps set up deployment when running `make start` for the first time.
You can choose to run the application in standard mode or test mode and with or without OAUTH2.
You can choose to run the application in standard mode or test mode, with or without OAUTH2, and which backend implementation to run (`java` or `js`).
You may change this later by running `make setup`.

## Backend implementations

Quickstart ships two interchangeable backend implementations behind the same HTTP API ([quickstart/common/openapi.yaml](quickstart/common/openapi.yaml)). Both listen on `BACKEND_PORT` (default `8080`), share the same env files under [quickstart/docker/backend-service/](quickstart/docker/backend-service/), the same `onboarding` volume, and the same cookie + CSRF auth surface (oauth2 and shared-secret).

| Backend | Stack | Ledger transport | Source |
|---------|-------|------------------|--------|
| `java` (default) | JDK 21, Spring Boot 3.4 | gRPC (`canton:3901`) | [quickstart/backend/](quickstart/backend/) |
| `js` | Node 22, TypeScript, Fastify | JSON Ledger API (`canton:3975`) | [quickstart/backend-js/](quickstart/backend-js/) |

Selection is persisted in `quickstart/.env.local` by `make setup` (which prompts for `BACKEND`). You can also override it per invocation:

```bash
make build BACKEND=js # build only the JS backend image
make start BACKEND=js # bring up the stack with the JS backend in place of the Java service
```

Switching backends requires a clean restart so Postgres state and onboarding volumes are recreated:

```bash
make clean-all && make start BACKEND=js
```

`make build-daml` runs only the codegen the active backend consumes — `:daml:tsCodegen` (TypeScript bindings under [quickstart/backend-js/generated/](quickstart/backend-js/generated/)) for `BACKEND=js`, and `:daml:codeGen` + `distTar` (Java bindings) otherwise. The JS Compose override at [quickstart/docker/backend-js/compose.yaml](quickstart/docker/backend-js/compose.yaml) uses Docker Compose `!reset` / `!override` directives, so **Docker Compose v2.24 or newer is required** when running with `BACKEND=js`.

## Debugging TL;DR

If a container fails to start, there are a few things to try:

- Ensure Docker Compose is configured to allocate enough memory. The recommended minimum total memory is 8 GB.
- Start fresh with `make clean-all` and then manually delete all Docker images and volumes.

**Note**: The CN Quickstart uses Java SDK version `Eclipse Temurin JDK version 21` which runs within the Docker container. This information is specified in `quickstart/compose.yaml` and `.env`.
**Note**: When running the default Java backend (`BACKEND=java`), the CN Quickstart uses Java SDK version `Eclipse Temurin JDK version 21` inside the Docker container. This information is specified in `quickstart/compose.yaml` and `.env`. The Node.js backend (`BACKEND=js`) uses the Node 22 image defined in [quickstart/docker/backend-js/Dockerfile](quickstart/docker/backend-js/Dockerfile).

If you need assistance, please follow these directions to gather the log information needed for debugging:
1. `make setup` # optional
Expand All @@ -87,7 +112,7 @@ If you need assistance, please follow these directions to gather the log informa
## Available make targets

Run `make help` to see a list of all available targets.
Read the [FAQ Make target reference](9https://docs.digitalasset.com/build/3.3/quickstart/troubleshoot/cnqs-faq.html#cn-app-quickstart-make-target-reference) for a detailed list of make targets and their descriptions.
Read the [FAQ Make target reference](https://docs.canton.network/appdev/quickstart/project-structure#make) for a detailed list of make targets and their descriptions.

## Topology

Expand Down Expand Up @@ -215,6 +240,8 @@ working_dir: /app

This configuration demonstrates how the `backend-service` relies on the Quickstart-provided infrastructure. Quickstart automates much of the local environment setup for LocalNet, allowing you to prioritize application development. As you progress toward deployment and explore cloud orchestration, a deeper grasp of service configuration is invaluable. For now, consider these services a ready-to-use infrastructure foundation.

> **Note**: the YAML above is the resolved configuration for the default Java backend. When running with `BACKEND=js`, the same `make compose-config` command produces a Node.js variant: the `image` is the `backend-js` Node 22 image, `LEDGER_PORT` is `3975` (the JSON Ledger API port instead of the gRPC port `3901`), and the bind mount sources from [quickstart/backend-js/](quickstart/backend-js/) instead of `backend/build/distributions/backend.tar`. All other fields (env files, onboarding volume, `BACKEND_PORT`, dependencies on `pqs-app-provider` and `splice-onboarding`) are identical.

Then explore `register-app-user-tenant`, the service that registers AppUser tenants to the `backend-service`. This allows end users from the AppUser organization to log in and quickly start the web UI. That, in turn, ties the AppUser Identity Provider to the AppUser primary party ID. If the end user is logged in through this Identity Provider, the user can then act as the AppUser primary party. The `register-app-user-tenant` service utilizes functionality provided by the `splice-onboarding` module to make the task as simple as possible.

This step can also be performed manually through the web UI if you log in to Quickstart as `app-provider` and navigate to the tenants tab. At that tab, you can also see a list of registered tenants and verify that the `AppUser` tenant was automatically pre-registered for you by `register-app-user-tenant`.
Expand Down Expand Up @@ -261,8 +288,8 @@ The `AppUser` organization is registered on the Quickstart startup by calling th

| Service | Port | Description |
|---------|------|-------------|
| Backend Service | 8080 | Spring Boot backend for Licensing workflow |
| Backend Debug (JVM) | 5005 | Remote JVM debugging (when `DEBUG_ENABLED=true`) |
| Backend Service | 8080 | Spring Boot (Java) **or** Fastify (Node.js, `BACKEND=js`) backend for the Licensing workflow |
| Backend Debug (JVM) | 5005 | Remote JVM debugging — Java backend only, when `DEBUG_ENABLED=true` |

## Canton Participant Ledger API

Expand Down Expand Up @@ -503,10 +530,10 @@ Run:
```bash
make restart-backend
```
This target restarts the backend, handles dependent services (e.g., register-app-user-tenant), and rebuilds the service if needed.
This target restarts the backend, handles dependent services (e.g., register-app-user-tenant), and rebuilds the service if needed. It works for both backends — it rebuilds and recreates whichever implementation the active `BACKEND` value (set in `.env.local` by `make setup`, or overridden per command) selects.

#### Debug backend service
Enable remote JVM debugging by setting:
Remote debugging via `DEBUG_ENABLED=true` is **Java-backend only**. Enable remote JVM debugging by setting:
```bash
export DEBUG_ENABLED=true
make restart-backend
Expand All @@ -520,6 +547,8 @@ Configure your IDE (IntelliJ, VS Code) to attach to port 5005 for step-through d
Example in IntelliJ Idea
![remote-debug-settings](sdk/docs/images/remote-debug-settings.png)

The Node.js backend (`BACKEND=js`) does not expose a Node inspector by default; `DEBUG_ENABLED=true` is a no-op in JS mode. To attach a Node debugger, run the JS backend locally outside Docker (`cd quickstart/backend-js && npm install && node --inspect=0.0.0.0:9229 ...`) or extend [quickstart/docker/backend-js/start.sh](quickstart/docker/backend-js/start.sh) to pass `--inspect` and publish port 9229 from [quickstart/docker/backend-js/compose.yaml](quickstart/docker/backend-js/compose.yaml).

### Viewing logs
For interactive local log inspection we recommend lnav (https://lnav.org/). Install the Canton log format and use it to view ``*.clog`` files. Example Canton lnav format definition:
https://github.com/hyperledger-labs/splice/blob/main/canton/canton-json.lnav.json
Expand Down
8 changes: 4 additions & 4 deletions nix/dpm.nix
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{ pkgs ? import <nixpkgs> {} }:

let
dpmVersion = "3.4.11";
dpmVersion = "3.5.2";
system = pkgs.stdenv.hostPlatform.system;
os = if pkgs.stdenv.isDarwin then "darwin" else "linux";
arch = if pkgs.stdenv.isAarch64 then "arm64" else "amd64";

dpmHashes = {
"x86_64-linux" = "sha256:1k9csx67s81jzr02qaa6ggh1hps4m1rd3yrpxrp1ly5mv2w2hwqp";
"aarch64-linux" = "sha256:162nasjhrh8vhn2j3hqswi8w7q1xnn7njcqzdkfk9aq8x1gq9lgw";
"aarch64-darwin" = "sha256:1i10yqf3a2i5fkhyhkk3dw35jbjdpxp236wdjz31d9z5xz80zg5w";
"x86_64-linux" = "sha256:015npjj4npryg4c7k98g64zlnh4bx4jrwvbkvnhwsj7iniyfjr8c";
"aarch64-linux" = "sha256:0f9xbpbcl58ml8mfls4wgqc0gcnfkvivjxd20xhfd1lgls8nmbhq";
"aarch64-darwin" = "sha256:1srqpwglzljk0yiszb90bkp1b368a08dl95j77j72ijwa6hv2igr";
};
dpmHash = dpmHashes.${system} or (throw "Unsupported system: ${system}");
in
Expand Down
6 changes: 3 additions & 3 deletions quickstart/.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## Variables for substitution in docker-compose
## Container specific variables are placed in the respective container's --env-file

DAML_RUNTIME_VERSION=3.4.11
SPLICE_VERSION=0.5.3
DAML_RUNTIME_VERSION=3.5.2
SPLICE_VERSION=0.6.5
DOCKER_NETWORK=quickstart

# jdk backend
Expand All @@ -13,7 +13,7 @@ OTEL_AGENT_VERSION=2.10.0
# for Vite hot reload
VITE_BACKEND_PORT=${BACKEND_PORT}

SCRIBE_VERSION=0.6.15
SCRIBE_VERSION=3.5.2
# canton network
SPLICE_APP_UI_NETWORK_NAME="Canton Network"
SPLICE_APP_UI_NETWORK_FAVICON_URL="https://www.canton.network/hubfs/cn-favicon-05%201-1.png"
Expand Down
28 changes: 25 additions & 3 deletions quickstart/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ endif
############################################################################
#### backend-service
############################################################################
# Backend implementation selector. Set via `make setup`; java (default) or js.
# Override per-invocation with `make <target> BACKEND=js` if needed.
BACKEND ?= java
ifeq ($(BACKEND),js)
DOCKER_COMPOSE_FILES += -f ./docker/backend-js/compose.yaml
endif

ifeq ($(RESOURCE_CONSTRAINTS_ENABLED),true)
RESOURCE_CONSTRAINT_CONFIG += -f ./docker/backend-service/resource-constraints.yaml
endif
Expand Down Expand Up @@ -158,12 +165,27 @@ build-frontend: ## Build the frontend application
cd frontend && npm install && npm run build

.PHONY: build-backend
build-backend: ## Build the backend service
./gradlew :backend:build
build-backend: ## Build the backend service (Java by default; Node when BACKEND=js)
ifeq ($(BACKEND),js)
$(MAKE) build-backend-js
else
./gradlew :backend:build -x :daml:tsCodegen
endif

.PHONY: build-backend-js
build-backend-js: docker-available build-daml ## Build the JS backend Docker image
$(call docker-compose, build backend-service)

# Skip the codegen the active backend doesn't consume. distTar produces backend.tar for the
# Java image; the JS image doesn't consume it, and including it in the JS path would
# transitively re-pull :daml:codeGen via :backend:compileJava.
.PHONY: build-daml
build-daml: ## Build the Daml model
./gradlew :daml:build distTar
ifeq ($(BACKEND),js)
./gradlew :daml:build -x :daml:codeGen
else
./gradlew :daml:build distTar -x :daml:tsCodegen
endif

.PHONY: docker-available
docker-available: ## Check if Docker CLI exists and is running
Expand Down
5 changes: 5 additions & 0 deletions quickstart/backend-js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
generated
src/token-standard/metadata.types.ts
src/token-standard/allocation.types.ts
Loading