Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 34 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,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 Down Expand Up @@ -215,6 +239,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 +287,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 +529,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 +546,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
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