Interacting with DAML Ledgers using HTTP JSON API

Reading Time: 2 minutes

In my last blog DAML: Getting started with building Templates, I covered how to write a smart contract using  DAML for your Distributed Application using Templates and how to test it using Scenarios. I would recommend you all to go through them before going forward with this blog. In this blog, we will explore on how to interact with DAML Ledger using HTTP JSON API.

How to write Application around DAML Ledger?

To write an application around DAML Ledger, you have to interact with Ledger API. By interaction, I mean multiple operations like Create, Fetch, Archive or modify contracts on Ledger.

We can access Ledger Api via:

  • HTTP JSON API
  • Java Binding
  • Scala Binding
  • gRPC

In this blog, we will talk about interaction with Ledger API using HTTP JSON API.

Let’s start with what is HTTP JSON API?

JSON or JavaScript Object Notation is an encoding scheme that is designed to let application to communicate with Server indefinite way. The main objective of this is to optimize HTTP requests and the size of data packages exchanged between clients and servers.

HTTP Methods:
Hypertext Transfer Protocol (HTTP) enables the communication between clients and servers. It also defines a set of request methods to perform a certain action for a given resource. JSON API supports GET, POST, PATCH and DELETE HTTP methods.

How to access Ledger using HTTP JSON API?

HTTP JSON API with Ledger provides different functionalities like:-

  • Creating Contracts.
  • Exercising multiple choices on contract.
  • Querying the current active contract.
  • Retrieving all known Parties.

Ledger provides multiple end points to perform different operations on DAML Ledger.

Creating Contracts:

Endpoint: /:ledgerId/v1/create

Using this endpoint and POST method, We can create a contract on Ledger by providing payload in the following format:-


{
  "templateId": "Iou:Iou",
  "payload": {
    "observers": [],
    "issuer": "rztds0vfs6hgd1np",
    "amount": "999.99",
    "currency": "USD",
    "owner": "rztds0vfs6hgd1np"
  }
}

If the request is successful then the response would be like:-

"result": {
        "agreementText": "",
        "contractId": "#474:0",
        "observers": [],
        "payload": {
            "observers": [],
            "issuer": "rztds0vfs6hgd1np",
            "amount": "999.99",
            "currency": "USD",
            "owner": "rztds0vfs6hgd1np"
        },
        "signatories": [
            "rztds0vfs6hgd1np"
        ],
        "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
    },
    "status": 200

Exercising Choices On Contract

Endpoint: /:ledgerId/v1/exercise

Using this endpoint and POST method, We can exercise choices on contract by providing payload in the following format:-

{
    "templateId": "Iou:Iou",
    "contractId": "#474:0",
    "choice": "Iou_Transfer",
    "argument": {
        "newOwner": "Alice"
    }
}

If the request is successful then the response would be like:-


{
    "result": {
        "events": [
            {
                "archived": {
                    "contractId": "#474:0",
                    "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
                }
            },
            {
                "created": {
                    "agreementText": "",
                    "contractId": "#475:1",
                    "observers": [
                        "kx8tm3t10cxlapn5"
                    ],
                    "payload": {
                        "iou": {
                            "observers": [],
                            "issuer": "rztds0vfs6hgd1np",
                            "amount": "999.99",
                            "currency": "USD",
                            "owner": "rztds0vfs6hgd1np"
                        },
                        "newOwner": "kx8tm3t10cxlapn5"
                    },
                    "signatories": [
                        "rztds0vfs6hgd1np"
                    ],
                    "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:IouTransfer"
                }
            }
        ],
        "exerciseResult": "#475:1"
    },
    "status": 200
}

Reading From Ledger

Endpoint : /:ledgerId/v1/query

Using this endpoint and POST method, We can fetch contracts by providing payload in the following format:-

{
    "templateIds": ["Iou:Iou"],
    "query": {"amount": 100.0}
}

If the request is successful then the response would be like:-

{
    "result": [
        {
            "agreementText": "",
            "contractId": "#470:0",
            "observers": [],
            "payload": {
                "observers": [],
                "issuer": "rztds0vfs6hgd1np",
                "amount": "100.0",
                "currency": "USD",
                "owner": "rztds0vfs6hgd1np"
            },
            "signatories": [
                "rztds0vfs6hgd1np"
            ],
            "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
        }
    ],
    "status": 200
}

Compared to Ledger API

Though JSON API makes it much easier to interact with Ledger to provide basic functionalities such as :

  • creating contracts
  • exercising choices on contracts
  • retrieving all known parties

but it still needs to use Ledger API for complex functionalities like :-

  • Inspecting transactions
  • Asynchronous submit/completion workflows
  • Ledger metaprogramming .

References