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
100 changes: 56 additions & 44 deletions content/canton/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,30 @@
title: Get Started
---

This guide covers the prerequisites and the basic project wiring for building on Canton with OpenZeppelin's Daml packages.
This page shows how to set up the Daml toolchain, build the OpenZeppelin packages, and use them in your own Daml project.

<Callout type="info">
These packages target the Canton 3.4.x baseline and are under active
development. Pin exact versions from the package manifests in
<Callout type="warn">
The packages are unaudited and have no release yet. Pin a source commit of
[`OpenZeppelin/canton-contracts`](https://github.com/OpenZeppelin/canton-contracts)
rather than copying version numbers from this page.
and take version numbers from its package manifests, not from this page.
</Callout>

## Prerequisites

- **JDK 21+**: the Daml toolchain runs on Java. Install any JDK 21 or newer - e.g. OpenJDK or Eclipse Adoptium both work - and make sure `JAVA_HOME` points at it.
- **DPM (Daml Package Manager)**: Digital Asset's package manager and SDK installer. Install it, then use it to provision the Daml SDK / Canton baseline:
- **JDK 21 or newer.** The Daml toolchain runs on Java. Set `JAVA_HOME` to the JDK.
- **DPM (Daml Package Manager).** DPM installs the Daml SDK and runs builds, tests, and the sandbox:

```bash
curl https://get.digitalasset.com/install/install.sh | sh
dpm install 3.4.11 # or the baseline pinned in your project's daml.yaml
```

- **A Daml project**: a directory with a `daml.yaml` (single package) or a `multi-package.yaml` (workspace of packages). New to Daml? Start with the [Daml documentation](https://docs.digitalasset.com/) and the [Canton Network overview](https://www.canton.network/).

## Add OpenZeppelin Packages
The packages target the Canton 3.4 baseline (SDK `3.4.11`, Daml-LF target `2.1`). Run `dpm install` in a project directory to install the SDK version that its `daml.yaml` or `multi-package.yaml` declares.

OpenZeppelin's Canton library is distributed as Daml packages: each primitive is its own DAR, so you add only the ones you need.
If you are new to Daml, read the [Daml documentation](https://docs.digitalasset.com/) and the [Canton guide to building and packaging](https://docs.canton.network/appdev/modules/m3-building-packaging) first.

<Callout type="warn">
Experimental and work in progress. All library packages are version 0.x,
unaudited, and not yet a stable public API: interfaces may change before a
1.0 release, and they are not intended for production use. They live under
[`experiments/`](https://github.com/OpenZeppelin/canton-contracts/tree/main/experiments)
in `OpenZeppelin/canton-contracts` and move to `packages/` when they are
released.
</Callout>
## Build the Packages

**1. Get the DARs.** The source of truth for production DARs is the [`dars/released/`](https://github.com/OpenZeppelin/canton-contracts/tree/main/dars) directory in `OpenZeppelin/canton-contracts`: it holds immutable DARs copied from tagged GitHub Releases, indexed in `dars/manifest.yaml` with the package IDs and SHA-256 digests operators need for verification and vetting. No production releases have been published yet, so for now build the library packages from source:
No DAR has a release yet, so build the packages from source:

```bash
git clone https://github.com/OpenZeppelin/canton-contracts.git
Expand All @@ -45,9 +34,31 @@ dpm install
dpm build --all
```

Library packages live under `experiments/` until their first release, grouped by category (`experiments/access/` for authorization and ownership, `experiments/security/` for operational security, `experiments/token/` for the Token Standard V2 (CIP-112) token and settlement package); released packages will live under `packages/`. Each package's DAR lands in its own `.daml/dist/` directory (for example `experiments/security/pausable-v1/.daml/dist/openzeppelin-pausable-v1-0.1.0.dar`).
To build one package, set `DAML_PACKAGE` to its directory. Build a package's dependencies first:

```bash
DAML_PACKAGE=packages/security/api-pausable-v1 dpm build
DAML_PACKAGE=packages/security/pausable-v1 dpm build
```

The packages are grouped by status and category:

**2. Declare them as data-dependencies.** In your project's `daml.yaml`, reference the built DARs under `data-dependencies` (not `dependencies`, which is for the SDK's own libraries):
| Directory | Contents |
| --- | --- |
| `packages/security/` | Pausable (pre-release) |
| `test/` | Test packages for `packages/` |
| `experiments/access/` | Access Control and Ownable (experimental) |
| `experiments/token/` | Token (CIP-0112) (experimental) |
| `experiments/test/` | Test packages for `experiments/` |
| `examples/` | Runnable projects that use the packages |

Each build writes its DAR to the `.daml/dist/` directory of the package, for example `packages/security/pausable-v1/.daml/dist/openzeppelin-pausable-v1-0.1.0.dar`.

Released DARs will go in [`dars/released/`](https://github.com/OpenZeppelin/canton-contracts/tree/main/dars), with package IDs and SHA-256 digests in `dars/manifest.yaml`. Participant operators use these values to verify and vet the packages.

## Add the Packages to Your Project

In the `daml.yaml` of your project, add each DAR under `data-dependencies`. The `dependencies` list is for SDK libraries only.

```yaml
sdk-version: 3.4.11
Expand All @@ -60,48 +71,49 @@ dependencies:
data-dependencies:
- ../canton-contracts/experiments/access/access-control-v1/.daml/dist/openzeppelin-access-control-v1-0.1.0.dar
- ../canton-contracts/experiments/access/ownable-v1/.daml/dist/openzeppelin-ownable-v1-0.1.0.dar
- ../canton-contracts/experiments/security/pausable-v1/.daml/dist/openzeppelin-pausable-v1-0.1.0.dar
- ../canton-contracts/packages/security/api-pausable-v1/.daml/dist/openzeppelin-api-pausable-v1-0.1.0.dar
- ../canton-contracts/packages/security/pausable-v1/.daml/dist/openzeppelin-pausable-v1-0.1.0.dar
build-options:
- --target=2.1
```

Adjust the paths to wherever you cloned the repo, and pin the exact versions from its package manifests. If you only need one primitive, list only that DAR.
Change the paths to match your clone. List only the DARs that you use, plus their dependencies: `openzeppelin-pausable-v1` needs `openzeppelin-api-pausable-v1`.

**3. Import and build.** Import the modules you declared and build your project:
The [Token](/canton/library/token) package also needs the Token Standard V2 DARs from `dars/vendor/` in `data-dependencies`. The token page lists them.

Import the modules and build:

```daml
import OpenZeppelin.PausableV1
import OpenZeppelin.Api.PausableV1 (Pausable, PausableView (..))
import qualified OpenZeppelin.PausableV1 as Pausable
```

```bash
# from your project root, with DPM on PATH
dpm build
```

Refer to each component's page for the module path to import and the templates and interfaces it exposes:

- [Access Control](/canton/library/access-control)
- [Ownable](/canton/library/ownable)
- [Pausable](/canton/library/pausable)
Each package page gives its module name, templates, and choices.

## Test Against a Local Canton Ledger
## Test Against a Local Ledger

Daml Script tests run in-memory by default, but you can point the same scripts at a real local Canton ledger over gRPC, which is useful for validating time semantics, party visibility, and DAR uploads before targeting a shared network:
`dpm test` runs Daml Script tests on an in-memory ledger. To check time behavior, party visibility, and DAR upload on a real ledger, run the same scripts against a local Canton sandbox over the Ledger API:

```bash
# start a local sandbox with your DAR uploaded
dpm sandbox --dar .daml/dist/<your-package>.dar
# start a sandbox with your DAR
dpm sandbox --static-time --ledger-api-port 6865 --dar .daml/dist/<your-package>.dar

# run a script against it over the Ledger API
# in a second terminal, run a script against it
dpm script --dar .daml/dist/<your-package>.dar \
--script-name My.Module:myScript \
--ledger-host localhost --ledger-port 6865
--ledger-host localhost --ledger-port 6865 --static-time
```

If your scripts control ledger time with `setTime`, start the sandbox with `--static-time` and pass `--static-time` to `dpm script` as well: both default to wall-clock time, and ledger time only moves forward.
Use `--static-time` on both commands if your scripts call `setTime`. A wall-clock ledger rejects `setTime`, and a static-time clock only moves forward.

A sandbox keeps its state between script runs. A second allocation of the same party hint fails, so give each script its own party hints.

## Explore Further
## Next Steps

- The **[Settlement (CIP-112)](/canton/settlement)** primitive shows how to compose the library into an atomic, value-moving settlement flow.
- The **[Reference Implementations](/canton/reference-implementations)** walk through complete application blueprints built on these pieces.
- The [Canton Improvement Proposals (CIPs)](https://github.com/canton-foundation/cips) repository holds the ecosystem standards these packages align with.
- Read the [Library overview](/canton/library) for the package design rules.
- Read the [Reference Implementations](/canton/reference-implementations) for complete application designs.
- See the [Canton Improvement Proposals (CIPs)](https://github.com/canton-foundation/cips) for the standards that the packages implement.
32 changes: 15 additions & 17 deletions content/canton/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,32 @@
title: OpenZeppelin for Canton
---

OpenZeppelin is building a suite of secure, reusable building blocks for the [Canton Network](https://www.canton.network/), the privacy-enabled network of applications built on [Daml](https://docs.digitalasset.com/). This section is the home for OpenZeppelin's Canton documentation: the general-purpose library, the settlement primitive, and the Reference Implementations that show how they fit together.

<Callout type="info">
The Canton ecosystem stack is under active development. Components are labelled
by maturity throughout these docs. Treat everything marked *experimental* as
a preview surface: interfaces may change, and it is not yet audited or intended
for production use.
OpenZeppelin builds reusable, security-focused [Daml](https://docs.digitalasset.com/) packages for applications on the [Canton Network](https://www.canton.network/). This section documents the library packages and the Reference Implementations that use them.

<Callout type="warn">
No package has a release or an audit yet. Do not use the packages in
production. Pausable is a pre-release package. Access Control, Ownable, and
Token are experiments: they will be redesigned before their first release,
and the redesign will change module names, choice signatures, and package
IDs.
</Callout>

## Library

Foundational Daml modules that other packages and applications compose on top of. See the [Library overview](/canton/library) for the design philosophy. These live in [`OpenZeppelin/canton-contracts`](https://github.com/OpenZeppelin/canton-contracts).

- **[Access Control](/canton/library/access-control)**: Role-based authorization for Daml workflows, with an admin role that grants and revokes other roles.
- **[Ownable](/canton/library/ownable)**: A single-owner authorization primitive for privileged actions, with ownership transfer.
- **[Pausable](/canton/library/pausable)**: An emergency stop mechanism that lets an authorized party halt and resume sensitive choices.

## Settlement
The packages live in [`OpenZeppelin/canton-contracts`](https://github.com/OpenZeppelin/canton-contracts). Each package is an independent DAR. See the [Library overview](/canton/library) for the design rules.

- **[Settlement (CIP-112)](/canton/settlement)**: An experimental, interface-shaped settlement engine for atomic multi-leg, value-moving delivery-versus-payment, built on the Token Standard V2 (CIP-112) interfaces. Implemented as the [`openzeppelin-tokenCIP112-v1`](https://github.com/OpenZeppelin/canton-contracts/tree/main/experiments/token/tokenCIP112-v1) package in `OpenZeppelin/canton-contracts`, with executable research and live-ledger evidence in [`OpenZeppelin/canton-specs`](https://github.com/OpenZeppelin/canton-specs).
- **[Access Control](/canton/library/access-control)**: role-based authorization. An admin issues role grants, and gated choices check the grant that the caller presents.
- **[Ownable](/canton/library/ownable)**: single-owner authorization with a two-step ownership transfer.
- **[Pausable](/canton/library/pausable)**: an emergency stop. Your template holds the flag, and gated choices refuse to run while it is set.
- **[Token (CIP-0112)](/canton/library/token)**: a token that implements the Token Standard V2 interfaces, with batch settlement, compliance hooks, and CIP-86 allowances.

## Reference Implementations

- **[Reference Implementations](/canton/reference-implementations)**: End-to-end application blueprints (DEX, Lending, Cross-Chain Stablecoin, Confidential Auction) that demonstrate how the library and settlement primitives compose into real applications.
The [Reference Implementations](/canton/reference-implementations) are target architectures for complete applications: a DEX, a lending protocol, a cross-chain stablecoin bridge, and a confidential auction.

## Where to Start

New to the Canton stack? Head to **[Get Started](/canton/get-started)** for prerequisites, toolchain setup, and how to add OpenZeppelin packages to a Daml project.
Go to [Get Started](/canton/get-started) to install the toolchain and add OpenZeppelin packages to a Daml project.

---

Expand Down
Loading
Loading