gRPC

If you want to write an application for the ledger API in other languages, you’ll need to use gRPC directly.

If you’re not familiar with gRPC and protobuf, we strongly recommend following the gRPC quickstart and gRPC tutorials. This documentation is written assuming you already have an understanding of gRPC.

Getting started

You can get the protobufs from a GitHub release, or from the daml repository here.

Protobuf reference documentation

For full details of all of the Ledger API services and their RPC methods, see Ledger API Reference.

Example project

We have an example project demonstrating the use of the Ledger API with gRPC. To get the example project, PingPongGrpc:

  1. Configure your machine to use the example by following the instructions at Set up a Maven project.
  2. Clone the repository from GitHub.
  3. Follow the setup instructions in the README. Use examples.pingpong.grpc.PingPongGrpcMain as the main class.

About the example project

The example shows very simply how two parties can interact via a ledger, using two Daml contract templates, Ping and Pong.

The logic of the application goes like this:

  1. The application injects a contract of type Ping for Alice.
  2. Alice sees this contract and exercises the consuming choice RespondPong to create a contract of type Pong for Bob.
  3. Bob sees this contract and exercises the consuming choice RespondPing to create a contract of type Ping for Alice.
  4. Points 2 and 3 are repeated until the maximum number of contracts defined in the Daml is reached.

The entry point for the Java code is the main class src/main/java/examples/pingpong/grpc/PingPongGrpcMain.java. Look at it to see how connect to and interact with a ledger using gRPC.

The application prints output like this:

Bob is exercising RespondPong on #1:0 in workflow Ping-Alice-1 at count 0
Alice is exercising RespondPing on #344:1 in workflow Ping-Alice-7 at count 9

The first line shows:

  • Bob is exercising the RespondPong choice on the contract with ID #1:0 for the workflow Ping-Alice-1.
  • Count 0 means that this is the first choice after the initial Ping contract.
  • The workflow ID Ping-Alice-1 conveys that this is the workflow triggered by the second initial Ping contract that was created by Alice.

This example subscribes to transactions for a single party, as different parties typically live on different participant nodes. However, if you have multiple parties registered on the same node, or are running an application against the Sandbox, you can subscribe to transactions for multiple parties in a single subscription by putting multiple entries into the filters_by_party field of the TransactionFilter message. Subscribing to transactions for an unknown party will result in an error.

Daml types and protobuf

For information on how Daml types and contracts are represented by the Ledger API as protobuf messages, see How Daml types are translated to protobuf.

Error handling

Tor the standard error codes that the server or the client might return, see the gRPC documentation .

For submitted commands, there are these response codes:

ABORTED
The platform failed to record the result of the command due to a transient server-side error or a time constraint violation. You can retry the submission. In case of a time constraint violation, please refer to the section Dealing with time on how to handle commands with long processing times.
INVALID_ARGUMENT
The submission failed because of a client error. The platform will definitely reject resubmissions of the same command.
OK, INTERNAL, UNKNOWN (when returned by the Command Submission Service)
Assume that the command was accepted, and wait for the resulting completion or a timeout from the Command Completion Service.
OK (when returned by the Command Service)
You can be sure that the command was successful.
INTERNAL, UNKNOWN (when returned by the Command Service)
Resubmit the command with the same command_id.