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
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- "go.mod"
- "go.sum"
- ".github/workflows/ci.yml"
- "install.sh"
- "docs/design/mockups/**.jsx"
- "frontend/**"
- "Makefile"
Expand All @@ -26,6 +27,7 @@ on:
- "go.mod"
- "go.sum"
- ".github/workflows/ci.yml"
- "install.sh"
- "docs/design/mockups/**.jsx"
- "frontend/**"
- "Makefile"
Expand Down Expand Up @@ -56,6 +58,9 @@ jobs:
go-version-file: go.mod
cache: false

- name: Validate install.sh syntax
run: sh -n install.sh

- name: Build
run: go build ./...

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ internal/ui/dist/*

# worktrunk configs
.config/wt.toml

tmp/
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ recommended) and 10 GB of free disk — see the
## Install

Through the dpm ([Daml Package Manager](https://docs.canton.network/sdks-tools/cli-tools/dpm)), in a project's `daml.yaml`. Ensure you remove the sdk-version field from the file. For example, if your current daml.yaml file is:

```yaml
sdk-version: 3.5.2
name: daml-test-1
Expand All @@ -35,6 +36,7 @@ dependencies:
```

You should use the following daml.yaml file:

```yaml
#sdk-version: 3.5.2
name: daml-test-1
Expand All @@ -47,21 +49,26 @@ dependencies:
- daml-script
components:
- damlc:3.5.2
- daml-script:3.5.2
- oci://ghcr.io/bitdynamics-ab/canton-devkit:latest
```

then `dpm install package` and use it as `dpm localnet <cmd>`.

For a standalone binary, use the quick-install script:
For a quick standalone install on macOS or Linux:

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

Homebrew, APT for
Debian/Ubuntu, manual platform downloads, and `go install` are also
supported — the [installation guide](docs/getting-started.md) covers each
path step by step.
As a standalone binary, you can also download the archive for your
platform (macOS arm64, Linux amd64, Windows amd64) from the
[releases page](https://github.com/bitdynamics-ab/canton-devkit/releases)
and verify it against the `SHA256SUMS` file published with each release.
Homebrew (`brew install bitdynamics-ab/canton-devkit/canton-devkit`), an APT
repository for Debian/Ubuntu, and `go install` are also supported — the
[installation guide](docs/getting-started.md) covers each path
step by step.

Both paths ship the same binary; `dpm localnet <cmd>` and
`canton-devkit localnet <cmd>` are interchangeable everywhere below.
Expand All @@ -78,16 +85,18 @@ canton-devkit localnet down demo

The command surface covers the full development loop:

| Area | Commands |
|------|----------|
| Lifecycle | `up` `down` `stop` `start` `restart` `pause` `resume` `clean` `list` `status` `logs` |
| Host checks | `doctor` — the same preflight `up` runs, with remediation hints |
| App wiring | `env` `creds` — endpoints, party IDs, and JWTs for tests and CI |
| DAR management | `dar upload / list / info / download / diff / remove / build-upload / watch` |
| Ledger inspection | `contracts ls / watch` · `tx ls / replay` |
| Tokens | `token create / mint / transfer / burn / balance` |
| State | `snapshot` / `restore` — a portable `.tgz` of a network's full state |
| Versions | `versions` — pinned Splice releases, keyed by commit SHA |

| Area | Commands |
| ----------------- | ------------------------------------------------------------------------------------ |
| Lifecycle | `up` `down` `stop` `start` `restart` `pause` `resume` `clean` `list` `status` `logs` |
| Host checks | `doctor` — the same preflight `up` runs, with remediation hints |
| App wiring | `env` `creds` — endpoints, party IDs, and JWTs for tests and CI |
| DAR management | `dar upload / list / info / download / diff / remove / build-upload / watch` |
| Ledger inspection | `contracts ls / watch` · `tx ls / replay` |
| Tokens | `token create / mint / transfer / burn / balance` |
| State | `snapshot` / `restore` — a portable `.tgz` of a network's full state |
| Versions | `versions` — pinned Splice releases, keyed by commit SHA |


Token commands support both Canton token-standard generations, routed
per instrument: [CIP-0056](https://github.com/global-synchronizer-foundation/cips/blob/main/cip-0056/cip-0056.md)
Expand Down
16 changes: 8 additions & 8 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,28 @@ contains the `canton-devkit` binary plus `LICENSE` and `README.md`. Every
release also publishes a single `SHA256SUMS` file covering all archives.

### Quick install (macOS arm64 / Linux amd64)

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

Or with `wget`:

```bash
wget -qO- https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | sh
wget -qO- https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh
```

Options (pass as environment variables):

```bash
# Pin a specific version
curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | VERSION=0.12.2 sh
curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | VERSION=0.12.2 sh

# Custom install directory
curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | INSTALL_DIR=/usr/local/bin sh
curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | INSTALL_DIR=/usr/local/bin sh
```

The installer detects your platform, downloads the matching archive from
the [releases page](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases),
the [releases page](https://github.com/bitdynamics-ab/canton-devkit/releases),
verifies the SHA-256 checksum, and installs to `~/.local/bin` by default.
It warns when that directory is not on your `PATH`.

Expand All @@ -122,8 +121,9 @@ brew update
brew upgrade canton-devkit
```

The formula downloads platform-specific release tarballs from the
[distribution repo releases page](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases).
The formula downloads platform-specific release tarballs from the tap
repository release page:
[`bitdynamics-ab/homebrew-canton-devkit/releases`](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases).

> See the [Homebrew guide](homebrew.md) for the tap layout and how the
> formula is kept in sync on each release.
Expand Down
4 changes: 3 additions & 1 deletion docs/homebrew.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ following the standard Homebrew tap layout.

This source repository does not keep a `Formula/` directory. Homebrew
distribution files are maintained in `homebrew-canton-devkit`; this repository only
keeps the release helper script and docs that describe the process.
keeps the canonical `install.sh` script and docs that describe the process.
The tap repository keeps the Homebrew formula, APT repository metadata,
and a redirecting `install.sh` for backward compatibility.

## Install

Expand Down
6 changes: 6 additions & 0 deletions docs/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ tar -xzf canton-devkit_v0.7.0_linux_amd64.tar.gz
./canton-devkit localnet --help
```

For macOS arm64 and Linux amd64, a scripted installer is also available:

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

> **Version-string asymmetry:** the standalone archive filenames keep the
> `v` prefix (`canton-devkit_v0.7.0_linux_amd64.tar.gz`), matching the
> git tag, while the DPM/OCI tag strips it
Expand Down
143 changes: 143 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/sh
# Canton DevKit installer
# Usage: curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh
#
# Environment variables:
# VERSION - pin a specific version (e.g. VERSION=0.12.2)
# INSTALL_DIR - override install location (default: ~/.local/bin)

set -eu

REPO="bitdynamics-ab/canton-devkit"
GITHUB_API="https://api.github.com/repos/${REPO}/releases/latest"
GITHUB_DL="https://github.com/${REPO}/releases/download"
DEFAULT_INSTALL_DIR="${HOME}/.local/bin"

info() { printf '[canton-devkit] %s\n' "$*"; }
error() { printf '[canton-devkit] ERROR: %s\n' "$*" >&2; exit 1; }

fetch() {
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$1"
elif command -v wget >/dev/null 2>&1; then
wget -qO- "$1"
else
error "need 'curl' or 'wget' to download files"
fi
}

detect_platform() {
os="$(uname -s)"
arch="$(uname -m)"

case "${os}" in
Darwin) os="darwin" ;;
Linux) os="linux" ;;
*) error "unsupported OS: ${os} (supported: macOS, Linux)" ;;
esac

case "${arch}" in
arm64 | aarch64) arch="arm64" ;;
x86_64 | amd64) arch="amd64" ;;
*) error "unsupported architecture: ${arch} (supported: arm64, amd64)" ;;
esac

if [ "${os}" = "darwin" ] && [ "${arch}" != "arm64" ]; then
error "macOS builds are only available for Apple Silicon (arm64), got: ${arch}"
fi
if [ "${os}" = "linux" ] && [ "${arch}" != "amd64" ]; then
error "Linux builds are only available for x86_64 (amd64), got: ${arch}"
fi

PLATFORM="${os}_${arch}"
}

resolve_version() {
if [ -n "${VERSION:-}" ]; then
info "using pinned version: ${VERSION}"
return
fi

info "fetching latest version from GitHub..."
VERSION=$(
fetch "${GITHUB_API}" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\{0,1\}\([^"]*\)".*/\1/p'
)

if [ -z "${VERSION}" ]; then
error "could not determine latest version from GitHub API"
fi

info "latest version: ${VERSION}"
}

download_and_verify() {
TARBALL="canton-devkit_v${VERSION}_${PLATFORM}.tar.gz"
TARBALL_URL="${GITHUB_DL}/v${VERSION}/${TARBALL}"
CHECKSUMS_URL="${GITHUB_DL}/v${VERSION}/SHA256SUMS"

TMPDIR="$(mktemp -d)"
trap 'rm -rf "${TMPDIR}"' EXIT

info "downloading ${TARBALL}..."
fetch "${TARBALL_URL}" >"${TMPDIR}/${TARBALL}" || error "download failed: ${TARBALL_URL}"

info "downloading SHA256SUMS..."
fetch "${CHECKSUMS_URL}" >"${TMPDIR}/SHA256SUMS" || error "download failed: ${CHECKSUMS_URL}"

info "verifying checksum..."
EXPECTED=$(grep " ${TARBALL}\$" "${TMPDIR}/SHA256SUMS" | awk '{print $1}')
if [ -z "${EXPECTED}" ]; then
error "no checksum found for ${TARBALL} in SHA256SUMS"
fi

if command -v sha256sum >/dev/null 2>&1; then
ACTUAL=$(sha256sum "${TMPDIR}/${TARBALL}" | awk '{print $1}')
elif command -v shasum >/dev/null 2>&1; then
ACTUAL=$(shasum -a 256 "${TMPDIR}/${TARBALL}" | awk '{print $1}')
else
error "need 'sha256sum' or 'shasum' to verify download"
fi

if [ "${EXPECTED}" != "${ACTUAL}" ]; then
error "checksum mismatch!\n expected: ${EXPECTED}\n actual: ${ACTUAL}"
fi
info "checksum verified."
}

install_binary() {
INSTALL_DIR="${INSTALL_DIR:-${DEFAULT_INSTALL_DIR}}"

mkdir -p "${INSTALL_DIR}"

info "extracting canton-devkit to ${INSTALL_DIR}..."
tar -xzf "${TMPDIR}/${TARBALL}" -C "${TMPDIR}"
mv "${TMPDIR}/canton-devkit" "${INSTALL_DIR}/canton-devkit"
chmod +x "${INSTALL_DIR}/canton-devkit"

info "installed canton-devkit v${VERSION} to ${INSTALL_DIR}/canton-devkit"

case ":${PATH}:" in
*":${INSTALL_DIR}:"*) ;;
*)
printf '\n'
info "WARNING: ${INSTALL_DIR} is not in your PATH."
info "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
printf '\n export PATH="%s:$PATH"\n\n' "${INSTALL_DIR}"
;;
esac
}

main() {
info "Canton DevKit Installer"
printf '\n'

detect_platform
resolve_version
download_and_verify
install_binary

printf '\n'
info "Done. Run 'canton-devkit --help' to get started."
}

main
Loading