Upload daml model to Canton

Hi team,

After practicing a while on the examples provided in the code, I’m planning to use my own daml code and run it in my own canton network setup.

According to the examples, I need to upload (participant1.upload.dars) for the DAR file, and when we start working on the test with REPL, we also import some model-related class (such as Iou, Paint, etc) for command construction.

Supposed that I have my own daml code and my objective is to put it into my Canton setup. What is the right way to do so? My first thought is,

  1. code in Studio and unit test my model
  2. compile to DAR
  3. codegen to Scala (or Java?)
  4. upload item (2) and pass item (3) through REPL for testing / demonstration.

While I’m still trying how to do so, any suggestions / hints are most welcome.

Thanks a lot.



Hi kc,

Your experiments with a Daml model uploaded to a Canton participant always go through the Ledger API. There are the following ways how to access the Ledger API:

  1. Use Daml Navigator.
  2. Use the Ledger API bindings in the Canton console.
  3. Build your custom front-end for the Ledger API (or the JSON API).

The examples in the Canton documentation mostly use the Ledger API bindings in the Canton console and the Ledger API commands are built using the Scala codegen for the Daml models. So if you want to go down that route, use Scala codegen for your own Daml models and load the JAR file in the Canton console or your script on the fly, as explained by @Ratko_Veprek below.

1 Like

You can also load the jar on the fly. If you have a canton script, you can use Ammonites


to load the jar. After that statement, you need to place three lines:


After these lines, you can import the symbols loaded in the jar.

1 Like

Thanks @Andreas_Lochbihler and @Ratko_Veprek for your prompt reply.

I have tested JSON-API and things are working fine. But for demonstration purpose it is not that convenient as I always need to refer to different JWT and different party ID. It’s much better if I can use the Canton Console.

So far I can upload the DAR to all participant nodes. What I’m missing is the JAR file that I can either load it when starting my console or through Ammonites. How can I get the JAR file you two mentioned in the reply? I tried codegen with scala but it seems everything is in Scala. If you can point me where to get the JAR file that will be great.

Once again, thanks a lot and i’m so excited to see my model work on a customized Canton network.


1 Like

Hi @kctam

Have a look at the Daml Scala Bindings Docs: Scala bindings — Daml SDK 1.13.1 documentation

Once you can build your jar accordingly, you can load the jar into the Canton process as described.



Hi team,

I forget to close this. With help from @Ratko_Veprek I have successfully completed bringing my own model to a Canton setup, and now I can use the canton console (repl) to demonstrate my code.

And also thanks again to @Andreas_Lochbihler for your prompt response. I also tested JSON-API part: it also worked well.

Thanks again.

1 Like

I see that the Scala bindings are deprecated. Am I correct in assuming that the Java bindings would work just as well here?

1 Like

The deprecation means that the bindings are officially unsupported. They will remain, but without backwards compatibility guarantees.

1 Like

Thanks Ratko. The Java bindings should also work, right?

1 Like

Yes. The Java bindings are the primary supported way of interacting with the gRPC API.


When I try to load the jar in the script with interp.load.cp, it no longer finds the test class I put in the script. This actually happens to me any time I include those three lines with the @. E.g., I have a script Test.sc like this:


def run() = {

When I try to run it, I get:

@ Test.run()
cmd1.sc:1: value run is not a member of object ammonite.$sess.scripts.Test
val res1 = Test.run()
Compilation Failed

I think I am going to try to load the jar when launching Canton instead.

Hi Andreas,

Can you tell me how to add the jar to the class path for the Canton console? I’ve tried some obvious things like putting it in the CLASSPATH environment variable, and attempting to pass -cp or -classpath command line arguments to canton.

This also didn’t work:

JAVA_OPTS="-classpath path/to/my.jar" canton ...
1 Like

Why do you try to call Test.run()? The filename does not introduce a namespace, so run() is defined as is. The following works for me (tested with Canton 0.26.0):

  1. Start Canton with bin/canton -c examples/01-simple-topology/simple-topology.conf --bootstrap Test.sc. Test.sc contains exactly what you have in your example.
  2. Type run(); in the Console and hit return (without Test.). This prints hello.
1 Like

I’m afraid that I was too optimistic that you can simply add it to the class path. Ammonite, the Scala repl behind the Canton console, doesn’t take the classpath into account. I’ll update my answer above.

1 Like

Hmm, I am already using --bootstrap to load a setup.canton file, and canton doesn’t seem to accept multiple --bootstrap flags or colon-separated lists. I’ve been loading my tests script via the Canton CLI like so:

@ import $file.scripts.Test

Calling Test.run() works in this case until I try to add those three lines with the @ in the middle.

I feel like by this point I am hijacking this thread, and I will start a new thread if I need more help.

Thanks Andreas

1 Like