Skip to content

Repository files navigation

canton-specs

The home for all OpenZeppelin Canton docs, specs, and Reference Implementations (RIs): the CIP-0112 / Token Standard V2 settlement specs, the RI implementation code (the experimental settlement scaffold, a mock Token Standard V2 interface layer mirroring the splice-api-token-*-v2 packages, a deep settlement exemplar, and the compliance/identity experiments), the four RI architecture reports, the audit-readiness package + threat model, scope locks, research, and review provenance.

Repo split. The decoupled, ergonomic general Daml contracts library (oz-access-control / oz-ownable / oz-pausable) is owned by OpenZeppelin/canton-contracts. That repo is the source of truth for the reusable primitives and contains no RI/specs code. This repo holds the RI implementation that consumes the library and builds against a vendored snapshot of those primitives (evolve the primitives in canton-contracts, then refresh the snapshot here). The RI architecture reports in docs/ri-reports/ are living documents that link directly into the RI code (refresh with scripts/refresh-ri-anchors.sh). Originally seeded from the canton-contracts CIP-0112 settlement work branch.

Status: experimental. The M1 target is the CIP-0112 settlement primitive (not the superseded CIP-56 token foundation), alongside the reusable access-control primitives (see Access Control Library below). No stable M1 public API, CIP-0112 conformance, audit readiness, production readiness, or release readiness is claimed.

Scope

M1 target scope:

  • CIP-0112 / Token Standard V2 interface-aligned settlement primitive.
  • CIP-86 compatibility surface scoped to interoperate with the settlement work.
  • CIP-103 dApp and wallet-provider support components scoped to the settlement surface.
  • CIP-104 rewards support components scoped to the settlement surface.
  • Documentation, tests, security notes, and compatibility evidence.

Repository-local report surfaces:

CIP-86 / CIP-103 / CIP-104 are addressed as settlement-interop criteria, not standalone CIP-56-token deliverables. CIP-56 is background and migration evidence only. The experimental CIP-112 settlement scaffold lives under experiments/cip112-settlement and remains outside the committed public-library surface until the promotion boundary ADR's Splice DAR/import, license/NOTICE, package-ID/checksum, DPM wiring, and public API gates land:

Out of scope for this repo:

  • DEX, lending, payments, or auction business logic.
  • Production private integrations.
  • Production KYC, sanctions, custody, validator, bridge, or relayer services.
  • Full off-chain relayer infrastructure.
  • Year 2 components before approval.

Build Instructions

The M0 proof baseline accepts Daml SDK / Canton 3.4.11 through DPM only for the hello-world compile/deploy proof. M1 public API and Splice DAR import pins remain open until the CIP-112 promotion boundary gates are accepted.

For the M0 proof baseline:

  1. Install or expose DPM.
  2. Run dpm install 3.4.11.
  3. Run the accepted build command:
OZ_DAML_TOOLCHAIN=dpm dpm build

The production package is the repo root DPM package. It intentionally has no daml-script dependency. Disposable script/test code lives in the separate proof/ DPM package, which depends on the production DAR and owns daml-script.

Current M0 production DAR:

  • Path: .daml/dist/oz-canton-specs-0.0.0.dar
  • SHA-256: ae5419a2b4a6748af3f4ec77736b46d3b9ca40c82f7df8aa1229dff5f71f48d8
  • Main package ID: c14e2d83f3454f4c70fe9ef4c78818afce121129e195573914d0fa2d32a93ea0

Current M0 proof DAR:

  • Path: proof/.daml/dist/oz-canton-specs-hello-world-proof-0.0.0.dar
  • SHA-256: b76122f152fcd8df4a87c4a5de3cf989af3a5402b406ee89cd8638558a7bcaf2
  • Main package ID: 81ccf8122e709a188c0ec2d9759b8f0c9c8601d483967be8114fca9492c8cf84

The root and scaffold scripts use OZ_DAML_TOOLCHAIN=auto by default. Auto selection requires DPM and does not fall back to Daml Assistant. The scripts make ~/.dpm/bin/dpm visible for non-interactive shells when present and default DPM/DAML cache writes to the repo-local ignored .cache/ directory. The scaffold check uses scripts/dpm-env.sh inside this repo so standalone manual validation does not depend on the coordinating workspace root. Set OZ_DAML_TOOLCHAIN=dpm when manually validating the accepted M0 proof baseline. Daml Assistant use requires a superseding ADR or explicit exception.

The repo-local scripts/dpm-env.sh is intentionally kept byte-for-byte in sync with the coordinating root helper until an accepted vendoring step replaces the duplication. Root ./scripts/check-all.sh fails if the two helper copies drift. Manual validation machines should install or expose DPM and Java 21 before running scripts/manual-workflow-test.sh or scripts/check-scaffold.sh.

From the workspace root, run:

./scripts/check-all.sh
./scripts/test-all.sh
./scripts/manual-workflow-tests.sh

Because daml.yaml is committed, missing DPM tooling is a hard failure. Daml Assistant is not an accepted M0 proof path.

LocalNet Proof

The M0 LocalNet proof uses the root Canton sandbox config and Daml Script over the Ledger API gRPC endpoint from the separate proof/ package. DAR upload uses dpm script --upload-dar true; the sandbox participant vets the uploaded packages for this single-participant proof. Party allocation uses allocatePartyByHint inside HelloWorld.Proof:helloWorldProof.

From the workspace root:

./scripts/localnet-up.sh
./scripts/localnet-hello-world-proof.sh
./scripts/localnet-down.sh

localnet-up.sh requires tmux, starts Canton in a detached session, and waits for the Ledger API port to be reachable before returning. The proof script performs the same DPM bootstrap as the build/test scripts, so the default up/proof/down sequence works in non-interactive validation shells when DPM is installed on PATH or at ~/.dpm/bin/dpm.

Hello-World Scaffold

daml/HelloWorld/HelloWorld.daml is a minimal Daml source file for the M0 compile proof. It records its signatory, observer, controller, privacy, archive, failure, and migration assumptions in the source comments.

proof/daml/HelloWorld/Proof.daml is a disposable M0 LocalNet proof script. It is not public API and keeps the Daml Script dependency out of the production package.

Access Control Library

The first reusable primitives land here as three independent packages, each its own DAR with no dependency on the others — so a consumer imports only what it needs (e.g. just oz-pausable). This is the Daml-idiomatic form of OpenZeppelin's decoupled-module promise: independence is at the package boundary, since Daml has no inheritance and the unit of reuse is the DAR. The full rationale, the options weighed, and the Daml-specific genericity trade are documented in the canton-token-template docs/ARCHITECTURE.md.

Package Module Mirrors Notes
oz-access-control OpenZeppelin.AccessControl AccessControl.sol RoleGrant / RoleAdmin + pure requireRole / hasRole. Roles are Text ids (the bytes32 analogue) because Daml templates are monomorphic; a consumer layers a closed role sum on top via a roleId : MyRole -> Text wrapper.
oz-ownable OpenZeppelin.Ownable Ownable2Step.sol Ownership + OwnershipOffer. Transfer is a two-step handshake by necessity — a new owner is a signatory and cannot be bound unilaterally.
oz-pausable OpenZeppelin.Pausable Pausable.sol PauseState + whenNotPaused guard. Pause is origination control on a keyless ledger.

Each library package is daml-script-free. Tests and the example-consumer templates that demonstrate the usage pattern (RoleCheck, PauseCheck, the typed-wrapper bridge) live in the separate test/ package, which data-depends on all three DARs.

Build and test the whole workspace in dependency order:

dpm build --all          # builds all packages, including the three libraries
cd test && dpm test      # runs the shared test package, including experiments

Latest local run (2026-06-21, SDK 3.4.11 / Java 21): dpm build --all builds all packages and dpm test passes 60/60 scripts (14 AccessControl, 20 Cip112Settlement, 6 Ownable, 4 Pausable, 2 ComplianceShapeA, 6 ComplianceShapeB, 1 IdentityHookShapeA, 6 IdentityHookShapeB, 1 IdentityHookUpgrade).

Or build a single library standalone (proving its independence):

cd pausable && dpm build

Status: 0.1.0, unstable — these are not yet public API (no stability ADR), so DAR SHAs are intentionally not pinned here while the shape may still change.

CIP-112 Settlement Experiment

The experimental settlement package models a Token Standard V2-aligned request/instruction/allocation/settlement lifecycle with optional D1 and D2 extension points. It is designed against the hyperledger-labs/splice token-standard-v2-upcoming interfaces; the DAR import remains gated.

The package intentionally uses local stand-ins and toy holdings. Do not import or vendor Splice DARs from this repo until a later slice satisfies the promotion boundary ADR's published-DAR or reproducible-build evidence, package ID/checksum, Apache-2.0 license/NOTICE, and DPM dependency requirements.

License

MIT. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages