- What we built: a
dpm tracecommand that lets Canton developers look up a Daml transaction on a participant node and read it as an event tree. - How it works: a standalone Rust binary on the Ledger API, exposed through a component manifest.
- Why it matters: it shows how teams can add their own commands to
dpm, the Daml toolchain’s command line, without modifyingdpmitself. - Where it’s been tested: a local Canton sandbox, and a
cn-quickstartLocalNet with OAuth2 authentication and two participants.
Transaction tracing for Canton
Inspecting transactions is one of the most common things engineers do while building and debugging Daml applications on Canton. It’s a need that comes up in every environment a project moves through.
Moonsong Labs built dpm trace to make that step faster, and we’re publishing the component as an example of how Canton developers can extend the Daml toolchain with their own specialized tooling.
Read: Moonsong Labs launches Canton Readiness Guide
How dpm components work
dpm is the package manager and command-line entry point for the Daml development toolchain. It manages DARs, templates, and toolchain components, but its role is broader than dependency management. It is also an extensible launcher for additional commands.
That modular design means a team can add specialized tooling without modifying the dpm executable. A component supplies an executable and describes the command it contributes. Once the component is included in a Daml project, the new command appears alongside the standard dpm commands.
This repository demonstrates that extension model by adding transaction tracing to dpm:
Watch the demo
Why this demonstration matters
Transaction tracing is useful in its own right, but the larger point is how the capability was built. The component works directly against the Canton participant’s Ledger API, handles its own configuration and authentication flow, and integrates into the standard dpm experience without modifying dpm itself.
The same approach can support other project-specific capabilities, such as diagnostics, deployment helpers, package analysis, operational utilities, or integrations with external systems. Instead of growing one monolithic CLI, dpm provides a common entry point for independently developed components.
For Moonsong, this is also a practical example of the kind of engineering work we do on Canton. We identify gaps in the developer experience, work directly against the underlying infrastructure, and build focused tooling around it.
From a Rust binary to a dpm command
The trace component is implemented in Rust, completely separate from the dpm executable and source code. It connects directly to the participant’s Ledger API and calls UpdateService/GetUpdateById for a supplied update ID. This implementation expects a transaction update. The response is rendered as a readable event tree containing transaction metadata, creates, exercises, actors, witnesses, arguments, results, and contract payloads.
The Rust project is compiled into a trace binary. Its component manifest then exposes that binary as a command:
apiVersion: digitalasset.com/v1
kind: Component
spec:
commands:
- path: ./bin/trace
name: trace
desc: Inspect Daml ledger transactions
The example project references this component by its local path. As a result, users invoke it as though it were a native dpm command:
dpm trace '<update-id>' --profile sandbox
The component also provides profiles and authentication commands. A profile records the Ledger API endpoint, parties, transport settings, and authentication mode.
Testing it against real ledger environments
The trace-probe example exercises the component in two environments.
The first is a local Canton sandbox without authentication. A small Daml model creates a Probe contract and exercises its Accept choice, producing a ProbeResult. The capture script returns the update IDs, and dpm trace displays the resulting create and exercise tree.
The second uses a cn-quickstart LocalNet with OAuth2 authentication and two participants. The operator belongs to the App Provider participant, while the counterparty belongs to the App User participant. Both can inspect the transactions they are involved in after authenticating their profiles.
The scenario also creates an authorized but uninvolved party. Although that party can connect to the Ledger API, it cannot retrieve the transaction because it is neither a stakeholder nor a witness. This distinction is important: authentication determines who may call the API, while Daml and Canton visibility rules determine what that caller may see.
The complete sandbox and authenticated LocalNet walkthrough is available in the trace-probe README
About Moonsong and Canton Network
Moonsong Labs is a registered Service Provider on the Canton Network ecosystem, with a Daml-certified engineering team focused on building production-grade applications and infrastructure for institutional finance.
Our Canton practice spans Daml application development, node infrastructure, asset workflows, and integrations across the network. This transaction tracing example is part of our broader goal to build practical tools and infrastructure that make it easier for institutions to design, operate, and extend applications on Canton.
