Canton interop with Java bindings

I have a little Daml application that I am trying to deploy to Canton. I’m roughly following this Getting Started example code:

https://www.canton.io/docs/stable/user-manual/tutorials/getting_started.html#executing-smart-contracts

One major thing I am doing differently is that I am trying to use the Daml / Java bindings rather than the Scala bindings, because the Scala bindings are deprecated. (I’m fairly certain that the Getting Started example is using the Scala bindings, because the Daml translations in the example are using case class-like semantics. That said, it is not easy tracking down how and where these bindings were generated.)

I hit a problem in my code when I get to the line that is equivalent to this one from the Getting Started guide:

  val iouTx = participant2.ledger_api.commands.submit_flat(Seq(bank), Seq(iouCreateCmd))

This submit_flat method takes a sequence of com.daml.ledger.api.v1.commands.Command, as can be seen here in the docs.

I track this com.daml.ledger.api.v1.commands.Command class down to a ledger-api-scalapb artifact with this search:

https://search.maven.org/search?q=fc:%20com.daml.ledger.api.v1.commands.Command

However, the Java bindings I have generated for my Daml templates have different command types. I initially get a com.daml.ledger.javaapi.data.CreateCommand, and I am able to convert this into a com.daml.ledger.api.v1.CommandsOuterClass.CreateCommand, but I’m not finding a way to get to a com.daml.ledger.api.v1.commands.Command.

It sort of seems like parts of the Canton API are catering to the Scala bindings, even though they are deprecated. Is there a way I can get a com.daml.ledger.api.v1.commands.Command out of my Java bindings so that I can continue along the path I am on? Should I take a step back and switch over to the Scala bindings? Is there some other approach I can take here?

Thanks!

2 Likes

You should be able to use toProtoCommand.

More generally, I would however recommend against using the Canton REPL to submit commands. Submit commands via the gRPC Ledger API or the JSON API and use the Canton REPL only for administrative tasks. That way, you can port your app easily to run on another ledger or test locally against Sandbox.

The Java quickstart tutorial shows you how to connect the Java bindings to any Ledger API.

1 Like

The Canton REPL commands work currently (Canton 0.26.0) only with the Scala bindings. The Java bindings for Daml models use different types and I am not aware of any conversion functions between the two.

As @cocreature said, the ledger API bindings in the Canton REPL are meant not for production use; they’re merely a developer convenience to quickly prototype something. The proper way is to go via the ledger gRPC API directly.

1 Like

Thank you @cocreature and @Andreas_Lochbihler for your responses! I have my path forward now.

I think the Canton documentation is great in regards to explaining design and architecture. Maybe it could use some love in regards to “how-to”. The Getting Started app I am using glosses over some stuff such as where the bindings come from. It’s also using deprecated Scala bindings, and some portions of the Canton API that should only be used for quick prototyping. I wonder if we could rework it to use Java bindings and the ledger API. But, if the Canton REPL is going to work with Java bindings in the future, it might make sense to wait for that.

2 Likes