Skip to content
Merged
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Web UI.

**Website:** [https://bitdynamics-ab.github.io/canton-devkit/](https://bitdynamics-ab.github.io/canton-devkit/)

**HackCanton Season 3 starter:**
[install → one working example → common breaks](https://bitdynamics-ab.github.io/canton-devkit/hackcanton-s3/).

Requires Docker and Compose v2, about 8 GB of free RAM for Docker, and
about 20 GB of free disk. See the
[installation guide](https://bitdynamics-ab.github.io/canton-devkit/getting-started/)
Expand Down Expand Up @@ -93,6 +96,7 @@ Source Markdown also lives under [`docs/`](docs/) for browsing in the
repository:

- Guides: [getting started](docs/getting-started.md) ·
[HackCanton Season 3 starter](docs/hackcanton-s3.md) ·
[explorer](docs/explorer.md) ·
[observability](docs/observability.md) ·
[dashboard customization](docs/dashboard-customization.md) ·
Expand Down
2 changes: 2 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ it includes OS/arch, Docker/Compose versions, and the check results.

## 6. Next steps

- [HackCanton Season 3 starter](hackcanton-s3.md) — install, one
working example, and the breaks that eat day-one time.
- [LocalNet lifecycle](localnet-lifecycle.md) — zero to a running
LocalNet, multiple instances, deterministic ports, and clean-up.
- [Tokens](tokens.md) — CIP-0112 token flows on LocalNet.
Expand Down
160 changes: 160 additions & 0 deletions docs/hackcanton-s3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# HackCanton Season 3 starter

canton-devkit runs and tests your Daml application in a LocalNet.
Both `dpm localnet <cmd>` and `canton-devkit localnet <cmd>` use the same command tree.

Telegram support channel: https://t.me/+ysKrAz_QALk5NTM0

## 1. Install

| Requirement | Why | Check |
|---|---|---|
| Docker Engine / Desktop | LocalNet runs as containers | `docker version` |
| ~8 GB free RAM for Docker | Splice needs memory (12 GB recommended) | Docker Desktop → Settings → Resources |
| ~20 GB free disk | Images + volumes | `df -h` |

Tested platforms: macOS arm64 (Apple Silicon), Linux amd64, Windows amd64.

### Fast path (macOS Apple Silicon / Linux x86_64)

```bash
curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh
```

The installer places the binary in `~/.local/bin` by default.
It warns if that directory is not on your `PATH`.
Open a new terminal after you install.

Homebrew:

```bash
brew tap bitdynamics-ab/canton-devkit
brew install bitdynamics-ab/canton-devkit/canton-devkit
```

**Windows (amd64):** download the `.zip` from
[GitHub Releases](https://github.com/bitdynamics-ab/canton-devkit/releases).
Follow the PowerShell steps in
[Installation & Getting Started](getting-started.md).
Docker Desktop needs the WSL 2 backend.

**Already have a Daml project?** Install DevKit as a DPM component
(`dpm install package`, then `dpm localnet …`).
Full `daml.yaml` steps are in that same guide.

Then check the host. This command does not change anything:

```bash
canton-devkit localnet doctor
```

Exit `0` means ready. Warnings do not fail the check.
Exit `2` means a check failed.
The output prints a fix you can copy.
`doctor` is the same preflight that `localnet up` runs.

## 2. One working example

Start a named LocalNet, then start a transferable demo token.
You do not need a DAR file for this.

```bash
canton-devkit localnet up demo
canton-devkit localnet status demo
canton-devkit localnet token demo --instance demo
canton-devkit localnet token balances --instance demo
```

What that does:

- `up demo` downloads Splice on first run and **waits until healthy**.
A cold start takes several minutes. That is normal.
If it stays on "waiting for healthy" until timeout, Docker memory is usually too low.
See the table below.

- `up` defaults to `--version latest` (the catalogue alias).
A new Token Standard V2 instrument needs Splice **0.6.11 or newer**.
Do not pin an older tag for this example.
List catalogue tags with `canton-devkit localnet versions`.

- `token demo --instance demo` allocates parties `demo-issuer` and `demo-holder`.
It creates a `DEMO` instrument and mints the initial supply to the holder.
This matches the Web UI **Launch demo token** button.
You must pass `--instance`.
The participant ledger endpoint comes from `status`.

- `token balances` prints the party × instrument matrix for the instance.

Optional. Move some DEMO.
On LocalNet you own both parties, so the transfer can settle in one step:

```bash
canton-devkit localnet token transfer --instance demo \
--instrument DEMO --from demo-holder --to demo-issuer --amount 250 --auto-accept
canton-devkit localnet token balances --instance demo
```

### Dashboard and app wiring

```bash
canton-devkit localnet ui
eval "$(canton-devkit localnet env demo)"
```

`env` exports endpoints, party IDs, and JWTs for tests and your app.
Those JWTs are **dev-only**.
They work against this LocalNet.
They do not work against DevNet, TestNet, or MainNet.

When you have your own DAR:

```bash
canton-devkit localnet dar upload ./my-app.dar --instance demo
```

Stop containers (data volumes stay):

```bash
canton-devkit localnet down demo
```

Remove the instance fully (volumes and registry state):
`canton-devkit localnet remove demo`.

## 3. Troubleshooting

Run `canton-devkit localnet doctor` before other commands.
Full write-ups are in [troubleshooting](troubleshooting.md).

| Symptom | Cause | Fix |
|---|---|---|
| `doctor` says **Docker daemon** FAILED | Docker is not running | Start Docker Desktop, or `sudo systemctl start docker` |
| `doctor` says **Compose v2** FAILED | Only Compose v1 is present | Upgrade so `docker compose version` works (`docker compose`, not `docker-compose`) |
| `up` hangs at "waiting for healthy", or Canton containers OOM-loop | Docker memory is below the version floor (~8 GiB for Splice 0.6.x) | Raise Docker Desktop → Settings → Resources to the value `doctor` prints. Two instances on 8 GB will OOM. |
| `PORTS_IN_USE` on `up` | Another instance or a stale container holds the port block | `canton-devkit localnet list`, then `localnet down <other>`. Or pick a different instance name. |
| Linux: `permission denied` on the Docker socket | User is not in the `docker` group | `sudo usermod -aG docker $USER`, then log out and back in |
| macOS: "cannot be opened because the developer cannot be verified" | Gatekeeper quarantine | `xattr -d com.apple.quarantine $(which canton-devkit)` |
| `command not found: canton-devkit` after the curl installer | `~/.local/bin` is not on `PATH` | Add it and open a new terminal |
| Instance name rejected | Names must be DNS labels | Lowercase `[a-z0-9-]`, 1 to 63 chars, start and end alphanumeric. No underscores, no `MyStack`. |
| `token create` / mint to another participant: package not vetted | Test-token DAR is missing on that participant | `token create --instance <name>` uploads and vets on every LocalNet participant. If the fetch failed: `localnet dar upload <dar> --instance <name> --all-participants` |
| Cannot mint or burn Amulet in the CLI or Web UI | Amulet has no developer mint/burn surface | Use your own instrument (`token demo` or `token create`) |
| Token or ledger commands cannot find a JWT after a failed `up` | `up` captures credentials only when it finishes | Re-run `localnet up` to completion. `localnet creds demo --role app-provider --format raw` prints a captured JWT |
| Web UI / Explorer shows stale ports after a restart | Docker reassigned ephemeral host ports | Re-read them from `localnet status demo`. DevKit re-captures within ~15 s. Or run `localnet restart demo`. |

Still stuck: run `canton-devkit localnet logs demo`
(repeat `--service <svc>` to filter).
Then file a
[GitHub issue](https://github.com/bitdynamics-ab/canton-devkit/issues)
with the full `doctor` output and the failing command.

## Next

- [Installation & Getting Started](getting-started.md). DPM, checksums, Windows, `go install`.

- [LocalNet lifecycle](localnet-lifecycle.md). Multiple instances, `--port-base`, pause / stop / down.

- [Tokens](tokens.md). Create / mint / transfer / burn beyond the demo.

- [Explorer](explorer.md). Active Contract Set and transactions in the Web UI.

- [Troubleshooting](troubleshooting.md), [FAQ](faq.md), [Known limitations](limitations.md).
4 changes: 3 additions & 1 deletion docs/localnet-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ embedded Web UI for the same operations.
This guide walks the full lifecycle: bring an instance up, inspect it,
run several at once, and clean up. See
[Installation & Getting Started](getting-started.md) first if you
haven't installed DevKit yet.
haven't installed DevKit yet. Hackathon teams: the
[HackCanton Season 3 starter](hackcanton-s3.md) is install, one working
example, and common breaks.

## Zero to running LocalNet

Expand Down
3 changes: 3 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Troubleshooting

Day-one setup (install, one working example, common breaks):
[HackCanton Season 3 starter](hackcanton-s3.md).

Failure modes and fixes. Start with `canton-devkit localnet doctor` —
it runs the same host preflight as `localnet up` (Docker CLI, daemon,
Compose v2, disk + memory headroom, platform, port availability; pass
Expand Down
1 change: 1 addition & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ node_modules/
# Edit the repo docs, not these pages. Hand-authored pages (index.mdx,
# 404.md, operations/) stay tracked.
src/content/docs/getting-started.md
src/content/docs/hackcanton-s3.md
src/content/docs/case-studies/
src/content/docs/guides/
src/content/docs/reference/
5 changes: 4 additions & 1 deletion website/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export default defineConfig({
sidebar: [
{
label: 'Getting Started',
items: [{ slug: 'getting-started' }],
items: [
{ slug: 'getting-started' },
{ slug: 'hackcanton-s3', label: 'HackCanton Season 3' },
],
},
{
label: 'Case studies',
Expand Down
1 change: 1 addition & 0 deletions website/docs-map.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

export const docsMap = [
{ src: 'getting-started.md', dest: 'getting-started', description: 'Install Canton DevKit as a DPM component or standalone binary on macOS, Linux, and Windows, and verify your host is ready for LocalNet.' },
{ src: 'hackcanton-s3.md', dest: 'hackcanton-s3', description: 'HackCanton Season 3 starter: install Canton DevKit, run one working LocalNet example, and fix the breaks that eat day-one time.' },
{ src: 'case-study-canton-devkit.md', dest: 'case-studies/running-canton-locally', description: 'A walkthrough of standing up a local Canton + Splice network with Canton DevKit — from booting LocalNet to working through Token Standard flows (CIP-0056 and CIP-0112) — across both the CLI and the Web UI.' },
{ src: 'localnet-lifecycle.md', dest: 'guides/localnet-lifecycle', description: 'Zero to a running Canton LocalNet — start, inspect, run multiple instances, pin ports, tear down, and answers to common questions.' },
{ src: 'explorer.md', dest: 'guides/explorer', description: 'Browse the Active Contract Set, recent transactions, and a ledger timeline of a running LocalNet from the Web UI — with CLI equivalents for scripting.' },
Expand Down
7 changes: 7 additions & 0 deletions website/scripts/sync-docs.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
escapeYaml,
renderPage,
} from './sync-docs.mjs';
import { docsMap as liveDocsMap } from '../docs-map.mjs';

const MAP = [
{ src: 'getting-started.md', dest: 'getting-started', description: 'Install and verify.' },
Expand Down Expand Up @@ -116,3 +117,9 @@ test('renderPage falls back to filename-derived title when no H1', () => {
});
assert.match(out, /title: "tokens"/);
});

test('HackCanton S3 starter is published at a stable deep-link path', () => {
const entry = liveDocsMap.find(e => e.src === 'hackcanton-s3.md');
assert.ok(entry, 'docs/hackcanton-s3.md must be in docs-map.mjs');
assert.equal(entry.dest, 'hackcanton-s3');
});
5 changes: 5 additions & 0 deletions website/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ The only prerequisite is Docker and at least 8 GB of available memory (12 GB
recommended) and 10 GB of free disk — see the
[installation guide](getting-started/).

**HackCanton Season 3:** the
[starter page](hackcanton-s3/) is install, one working example, and
the breaks that eat day-one time.

## Install

Follow [Installation & Getting Started](getting-started/) — it covers
Expand Down Expand Up @@ -46,6 +50,7 @@ canton-devkit localnet up demo # bring up a network named "demo"

## Guides

- [HackCanton Season 3 starter](hackcanton-s3/) — install, one working example, common breaks
- [LocalNet lifecycle](guides/localnet-lifecycle/) — zero to running,
multiple instances, deterministic ports, teardown
- [Contract explorer](guides/explorer/) — ACS, transactions, per-party views
Expand Down