How to fetch a contract from dumlhub Ledger via Java

Hi there,

Can you refer me to a documentation or example on how to fetch a certain contract from a Ledger (from damlHub) according to a predefined key (e.g: fetch a product contract by its productId key)

Thanks

Daml Hub exposes the JSON API which provides endpoints for fetching a contract by contract id and by contract key.

Thanks @cocreature.

The documentation lack to explain several things regarding the body:

  1. Is the templateId should be the full name? In the screenshot below its “Workflow.Workflow:Product”
  2. Is the key _1 is the name of the key (In the screenshot below it’s “productId”)
  3. Is the _2 is the value of the key? (In the screenshot below it “P1234-337”)
{
    "templateId": "Account:Account",
    "key": {
        "_1": "Alice",
        "_2": "abc123"
    }
}

image

postman smaple return 404 although the contract exists so i assume i mis understood the body:

{
    "templateId": "Workflow.Workflow:Product",
    "key": {
        "_1": "productId",
        "_2": "P1234-337"
    }
}

Response:

{
    "errors": [
        "HttpMethod(POST), uri: http://p4np49dc43hsdza3.daml.app/v1/stream/fetch%20"
    ],
    "status": 404
}

templateId is the template id of the contract you’re trying to fetch. As anywhere else in the JSON API where a template id is specified you can either use

<package ID>:<module>:<entity>

or if it’s unambiguous

<module>:<entity>

The key is not separated into name and value, it is only the value. In the example in the docs, the key is a tuple (Party, Text). Daml tuples are translated to records with fields _1, …, _n (docs) so that’s why the JSON representation looks like this.

Hi @cocreature ,

When you refer to the contract key, is it as below screenshot?

Can you see anything missing in the below request that prevents from 200OK to respond (response is the second screenshot)?

It depends on how your defined your key. Can you share the key definition of Product?

Are you referring to this?

I was thinking of the Daml definition but this is sufficient. Your request looks correct but I believe you’re contacting the wrong endpoint: You’re querying the streaming endpoint with a POST request. Try /v1/fetch instead of /v1/stream/fetch. The docs seem off there, I’ll make sure that gets fixed.

Still the same error.

Although i should have received 401 (instead of 404), maybe the Bearer token is wrong?
Should i place the token of the contract’s Party (e.g the Carrier in my example)

You have a %20 so a space at the end of your url.

Embarrassing…It works :smile:
Thanks @cocreature

@cocreature Can you advise on the best way to deserialize the returned JSON into a contract?

My question is not technical since i’m aware of kibraries such as Gson or Jackson. My question is wether there is a recommended way to create an instance of a contract by its corresponding json (it’s a huge one by the way)

My end game is to submit and exercise a Command with this contract

There is no recommended way to decode the JSON API responses in Java atm. You have to implement it yourself.

I’ll ask it differently:

I want to exercise a multi party submission command on a certain contract which i fetched from a Ledger.

According to my knowledge, for a single party submission, i need to create a com.daml.ledger.javaapi.data.Command and use the Ledger client to “submitAndWait” it.

My question is: Given a contractId, what are the steps to perform such operation (submit multi party command)

Is there a constructor like CreateAndExerciseCommand(templateId, createArguments, choice, choiceArgument) that receives the contractId as an argument?

If you want to exercise a choice on a contract id use ExerciseCommand instead of CreateAndExerciseCommand. You don’t need to fetch the contract for that. The command is also independent of whether you do a multi-command submission or not.

For a multi-party submission you need to set actAs and readAs on the commands.

Note though that you also need a token for those parties and Daml Hub does not issue multi-party tokens at the moment so while you can use that locally you cannot make multi-party submissions against hub.

@cocreature,

Is “Submit Multi” only supported in sandbox (via Java)?

I’m asking because i’m pretty sure it’s supported in DAML against damlhub…

It’s supported against any ledger. The issue is not the lack of ledger support in Daml Hub but the fact that the Hub IAM does not issue you a token for multiple parties.

I thought that “Submit Multi” for two parties receives as an input two separated tokens. According to you it requires a single token allocated for multiple parties and that’s not supported?

Exactly.

@liav To correct @cocreature slightly, you have to ask hub to create a multiparty token for you, which you can do using the cli damlhub-cli - npm, please see

damlhub-cli ledger multipartyToken

With that token you can make submitMulti requests as those are natural requests via the LedgerAPI. The only wrinkle is that all of the parties that you aggregate into a single token must be controlled by the party that created the ledger; which I think is true in your case.

2 Likes