Skip to content

Add Node.js example for Canton JSON Ledger v2 + PQS - #345

Open
sneg55 wants to merge 2 commits into
digital-asset:mainfrom
sneg55:node-happy-path-example
Open

sneg55 wants to merge 2 commits into
digital-asset:mainfrom
sneg55:node-happy-path-example

Conversation

@sneg55

@sneg55 sneg55 commented Apr 30, 2026

Copy link
Copy Markdown

Summary

Adds a minimal Node.js example demonstrating Canton JSON Ledger API v2 + PQS end-to-end in ~135 lines, using dpm codegen-js typed bindings end-to-end so the choice argument shape is checked at compile time.

The example (quickstart/examples/node-happy-path/) shows, in one file:

  1. Mint a shared-secret JWT for the Canton ledger API.
  2. Build a LedgerClient from @canton-network/core-ledger-client.
  3. Read active AppInstall contracts from the PQS Postgres replica.
  4. Exercise AppInstall_CreateLicense via JSON Ledger API v2, with the choice argument typed against Licensing.AppInstall.AppInstall_CreateLicense.
  5. Confirm the new License lands in PQS.

The README's gloss table points each thing the example skips at the package or pattern that would handle it in production code.

This directly answers #156 ("would have spared him hours") and #59 ("demonstrate the TypeScript ledger bindings, transcoder, and Canton JSON API v2 all working together").

Closes #156, #59.

Why typed bindings matter here

Calling dpm codegen-js against the licensing DAR produces typed Choice<T,C,R,K> references and a generated LicenseParams shape ({ meta: MetadataV1.Metadata }, where Metadata is { values: TextMap }).

Without those, common first-time mistakes are silent at compile time:

  • meta written as { data: ... } (the OpenAPI shape, not the wire shape)
  • params misnamed
  • AppInstall_CreateLicense misspelled

With them, all three are TS errors. The README explains this and the example sends Licensing.AppInstall.AppInstall.templateId directly to JSON v2 and (with the leading # stripped) to PQS — the only ledger-vs-PQS gotcha you cannot infer from OpenAPI.

Bundled changes (kept minimal)

  • integration-test/playwright.config.ts — passes --host-resolver-rules=MAP *.localhost 127.0.0.1 to Chromium. Docker publishes 127.0.0.1:3000; macOS / some Linux distros resolve *.localhost to ::1 first, so any host process bound to ::1:3000 can hijack the suite. Pinning to v4 makes the existing Playwright tests reproducible.
  • nix/shell.nixnodejs_20nodejs_22, adds nodePackages.pnpm. Required to build and run the example.
  • README.md (root) — small pointer to the example.

What's intentionally not here

  • A keycloak-master-fix sidecar to relax sslRequired on the master realm (a known issue for the integration-test suite on Keycloak 26.x). Security-sensitive enough to deserve its own review.
  • A DB_HOST_PORT decoupling for postgres host port. That touches the existing TEST_PORT test-mode plumbing and should be reviewed separately.

A follow-up PR is being prepared to propose a fuller quickstart/backend-node/ as a reference snapshot (opt-in via BACKEND_FLAVOR=node).

Test plan

For the reviewer, on a fresh clone of this branch:

  • nix develop (or install Node 22 + pnpm 9 manually).
  • From quickstart/: make setup (choose shared-secret), make build, make start.
  • Complete one onboarding flow in the UI so an AppInstall exists.
  • From quickstart/examples/node-happy-path/: pnpm codegen:daml && pnpm install && pnpm typecheck should be clean.
  • Run the example with LEDGER_API_URL, PQS_DATABASE_URL, AUTH_SHARED_SECRET, APP_PROVIDER_PARTY_ID set per the example's README; confirm the six log lines in the expected order.
  • make integration-test (Java side) is unchanged.
  • To verify typed bindings catch errors: temporarily change the choice argument to { params: { meta: { data: {} } } }; pnpm typecheck should fail with 'data' does not exist in type 'Metadata'.

sneg55 added 2 commits April 30, 2026 14:08
Closes digital-asset#156, digital-asset#59.

quickstart/examples/node-happy-path/ is a single-file ~135-line Node
script that mints a shared-secret JWT, builds a
@canton-network/core-ledger-client LedgerClient, reads active
AppInstalls from PQS, exercises AppInstall_CreateLicense via JSON
Ledger v2, and confirms the new License in PQS. The choice argument
is typed against the dpm codegen-js output, so a typo in `params`,
`meta`, or `values` is a compile error.

A small pnpm workspace consumes the codegen output (gitignored,
regenerated by `pnpm codegen:daml`). The README's gloss table points
each thing the example skips at the package or pattern that handles
it in production code.
- integration-test/playwright.config.ts: launch Chromium with
  --host-resolver-rules=MAP *.localhost 127.0.0.1. Docker publishes
  127.0.0.1:3000; macOS / some Linux distros resolve *.localhost to
  ::1 first, so a host process bound to ::1:3000 can hijack the suite.
  Pinning v4 makes the existing Playwright tests reproducible.
- nix/shell.nix: nodejs_20 -> nodejs_22, add nodePackages.pnpm.
  Required to build and run the new Node example.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a Node.js backend example to the QS

1 participant