Skip to content
Discussions/App Development/Using JSON API with CANTONForum ↗

Using JSON API with CANTON

App Development26 posts656 views6 likesLast activity Jun 2022
BE
BernardoOP
Jun 2022

I am trying to setup my canton arquitecture with json api,

When i try to create contracts with json api i get this error:

allocateParty creates a new party everytime you run it. So if you run your Daml Script multiple times you get different parties each time which sounds like that’s what’s been happening here: You’ve run it once via initializeUser and then once via allocateParties directly. I recommend to have initializeUser return LedgerParties and then only run that once. If you run it via daml start, you can set the --output-file flag via daml start --script-option --output-file=parties.json. For the Alice::… …

At first i tried with the commands in this post, but as i am creating my canton network i follow the example in documentation : Getting Started — Daml SDK 2.7.6 documentation

A participant is created, which connects to a domain, the dar file is uploaded, but it is not possible to create the contract,

What am i missing here?

CO
cocreature
Jun 2022

Can you share your Canton setup & config? How did you create the participant, connect the domain, …?

BE
Bernardo
Jun 2022

Participant1 (remote) config file:
image

Participant1 init:
image

Participant1 status:

Participant2 (remote) config file:
image

Participant2 init:
image

Participant2 status:

Domain (remote) config file:
image

Domain status:

To create contrats i use the party id in the parties.json file as you said in this topic:

Hello cocreature, thanks for the answer, I understood what i got wrong, and i already create a contract with JSON API, First my partyid was wrong, i got it from navigator: [image] ALICE: party-cf4ce109-c007-45d7-839e-2f7756e5e5de::1220124aba0791c61bac337ed9319ce99bf9e96259acb554c2fbb244d20155bcfc95 BOB: party-660bf503-c37d-4aca-88ed-b2df54d1e940::1220124aba0791c61bac337ed9319ce99bf9e96259acb554c2fbb244d20155bcfc95 I fill out asker with partyid ALICE and answerer with partyid BOB, This …
CO
cocreature
Jun 2022

Are you trying to do a multi-party submission, i.e., does your user have actAs & readAs rights for both Alice & Bob (or if you’re not using user management, do you have a token with actAs & readAs claims for both)?

All parties you submit for must be hosted on the same participant.

BE
Bernardo
Jun 2022

Yes, i want to create contracts with alice and exercise them with bob, (both remote participants) and then store the contracts in postgres.

I have a JWT token with actAs (partyID Alice) and readAs (partyID Bob), but i got these partyID from the json file created early whit this command:

daml start --script-option --output-file=parties.json

I was uploading the dar file on the participants and not in the domain.

participants.all.dars.upload(“Project/.daml/dist/Project-0.0.1.dar”)

Dar uploaded in the domain and now i am getting this error, and i have not changed the code, any clue?

Just to clarify, the party ids in this canton arquitecture ( Participant1, Participant2 and Domain) are the same as the ones created in the json file? because i uploaded that dar, correct?

Thank you

GA
Gary_Verhaegen
Jun 2022

The parties in the JSON file will be on the Canton participant if the daml script command that produced the JSON file was run agains that participant.

Party creation has nothing to do with DAR uploads; the fact that daml script can run a DAR does not mean that uploading that same DAR to a ledger has any effect.

It’s unclear that parties or party IDs are the problem in your screenshot, though. That screenshot does look like a missing DAR files on the Canton ledger.

BE
Bernardo
Jun 2022

Hello Gary, thanks for the answer, i understand now the connection between the JSON file and Canton, but i am still getting that error,

I run the command “daml start --script-option --output-file=parties.json” in remote domain that updated the JSON file.

I uploaded the dar in the remote domain with the comand:

participants.all.dars.upload(“Project/.daml/dist/Project-0.0.1.dar”)

and checked in both remote participants with the command:

participant1.dars.list()

participant2.dars.list()

Using Json Api in participant1 and with the parties in json file created by first command, i try to create a contract without success,

What am i doing wrong?

GA
Gary_Verhaegen
Jun 2022

Hi @Bernardo,

We’ll need a little bit more information on exactly how you’ve set things up here. First off, daml start is a development convenience tool that may not be suitable at all. It generally starts a sandbox and runs its scripts against it, which may not be related to any of your otherwise running participants.

Can you share, specifically:

  • Your daml.yaml.
  • Whether you run any other command than daml start (e.g. to start an additional participant, or the JSON API), and if so which ones.
BE
Bernardo
Jun 2022

Thank you for your support,

My yaml file:

sdk-version: 2.1.1
name: Project
source: daml
version: 0.0.1
init-script: Lights:initializeUser
dependencies:
- daml-prim
- daml-stdlib
- daml-script

My file.daml:

module Lights where

import Daml.Script

type RequestChangeId = ContractId RequestChange
type ChangeId = ContractId Change

data Place = Room | Living_Room | Hall | Conference_Room
deriving(Eq,Show)

data State = ON | OFF
deriving(Eq,Show)

-- LEDGER_PARTIES_BEGIN
data LedgerParties = LedgerParties with
  alice : Party
  bob : Party
-- LEDGER_PARTIES_END

template RequestChange
with
 asker : Party
 answerer : Party
 place : Place
 currentState : State
where
  signatory asker
  observer answerer

choice Accept : ChangeId
  with
    feedback : Text
    newState : State 
  controller answerer 
  do 
    assertMsg "A state cannot be changed for equal." (currentState /= newState)
    create Change with ..

template Change
with
  asker : Party
  answerer : Party
  place : Place
  newState : State
  feedback : Text
where
   signatory asker, answerer

 -- INITIALIZE_USER_BEGIN 
initializeUser : Script LedgerParties
 initializeUser = do
    partyAlice <- allocatePartyWithHint "alice" (PartyIdHint "alice")
    partyBob <- allocatePartyWithHint "bob" (PartyIdHint "bob")

    alice <- validateUserId "alice"
    bob <- validateUserId "bob"
    _ <- createUser (User alice (Some partyAlice)) [CanActAs partyAlice]
    _ <- createUser (User bob (Some partyBob)) [CanActAs partyBob]
    --pure()
    pure (LedgerParties partyAlice partyBob)

-- INITIALIZE_USER_END

To initialize Domain:

To initialize Participant1:

To initialize Participant2:

After Initialization in Domain (Participants connected):

Upload Dar in domain:

Check in Participant1:

start JSON API in participant1:

JSON API ERROR:

CO
cocreature
Jun 2022

Can you run daml damlc inspect-dar --json path/to/your/dar | jq '.main_package_id' to get the package id of the DAR you’re uploading and then check if it’s contained in the list of package ids you see in the JSON API log?

BE
Bernardo
Jun 2022


i get nothing

CO
cocreature
Jun 2022

.main_package_id wasn’t a placeholder. You should actually run that.

BE
Bernardo
Jun 2022

CO
cocreature
Jun 2022

You missed the dot before main_package_id.

BE
Bernardo
Jun 2022


sorry, now it worked

GA
Gary_Verhaegen
Jun 2022

Any chance you could get us the text of those messages instead of screenshots? It’s really hard to check whether that template ID is in the list given by the JSON API based on screenshots.

BE
Bernardo
Jun 2022

Of course,

daml damlc inspect-dar --json .daml/dist/Project-0.0.1.dar | jq ‘.main_package_id’

“3db632339c92e02b15d4c15df0cb4363f41a9ff91c7a8eecf7eb67a35ff07b54”

JSON API

DAML_SDK_VERSION=2.1.1 daml json-api --ledger-host 192.168.61.128 --ledger-port 5011 --http-port 7575 --allow-insecure-tokens
07-06-2022 11:35:00.790 [main] INFO com.daml.http.Main - Config(ledgerHost=192.168.61.128, ledgerPort=5011, address=127.0.0.1, httpPort=7575, portFile=None, packageReloadInterval=5 seconds, packageMaxInboundMessageSize=None, maxInboundMessageSize=4194304, tlsConfig=TlsConfiguration(false,None,None,None,None,REQUIRE,false,None), jdbcConfig=None, staticContentConfig=None, allowNonHttps=true, wsConfig=None, nonRepudiationCertificateFile=None, nonRepudiationPrivateKeyFile=None, nonRepudiationPrivateKeyAlgorithm=None, surrogateTpIdCacheMaxEntries=None), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:01.235 [http-json-ledger-api-akka.actor.default-dispatcher-6] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
07-06-2022 11:35:01.595 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.HttpService - HTTP Server pre-startup, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:01.932 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempting to connect to the ledger 192.168.61.128:5011 (600 attempts), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.697 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempt 1/600 succeeded!, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.702 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempting to connect to the ledger 192.168.61.128:5011 (600 attempts), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.707 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempt 1/600 succeeded!, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.708 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.HttpService - contractDao: None, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:03.437 [http-json-ledger-api-akka.actor.default-dispatcher-8] INFO com.daml.http.Main - Started server: (ServerBinding(/127.0.0.1:7575),None), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:36:07.481 [http-json-ledger-api-akka.actor.default-dispatcher-6] INFO com.daml.http.Endpoints - Incoming POST request on http://localhost:7575/v1/create from unknown, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”}
07-06-2022 11:36:11.659 [http-json-ledger-api-akka.actor.default-dispatcher-15] INFO com.daml.http.PackageService - new package IDs loaded: 86828b9843465f419db1ef8a8ee741d1eef645df02375ebf509cdc8c3ddd16cb, cc348d369011362a5190fe96dd1f0dfbc697fdfd10e382b9e9666f0da05961b7, 6839a6d3d430c569b2425e9391717b44ca324b88ba621d597778811b2d05031d, 99a2705ed38c1c26cbb8fe7acf36bbf626668e167a33335de932599219e0a235, e22bce619ae24ca3b8e6519281cb5a33b64b3190cc763248b4c3f9ad5087a92c, d58cf9939847921b2aab78eaa7b427dc4c649d25e6bee3c749ace4c3f52f5c97, 6c2c0667393c5f92f1885163068cd31800d2264eb088eb6fc740e11241b2bf06, 8a7806365bbd98d88b4c13832ebfa305f6abaeaf32cfa2b7dd25c4fa489b79fb, c1f1f00558799eec139fb4f4c76f95fb52fa1837a5dd29600baa1c8ed1bdccfd, 733e38d36a2759688a4b2c4cec69d48e7b55ecc8dedc8067b815926c917a182a, 65921e553a353588e950cbc87e98a127730e63295f7ad8d3adae952ef0133b3e, f20de1e4e37b92280264c08bf15eca0be0bc5babd7a7b5e574997f154c00cb78, 3f4deaf145a15cdcfa762c058005e2edb9baa75bb7f95a4f8f6f937378e86415, bfcd37bd6b84768e86e432f5f6c33e25d9e7724a9d42e33875ff74f6348e733f, 57b5c520512c24035057aa4c783cb7ac7f3f49db29806280962e188be7aadb66, 518032f41fd0175461b35ae0c9691e08b4aea55e62915f8360af2cc7a1f2ba6c, cb0552debf219cc909f51cbb5c3b41e9981d39f8f645b1f35e2ef5be2e0b858a, 76bf0fd12bd945762a01f8fc5bbcdfa4d0ff20f8762af490f8f41d6237c6524f, 852d8e3a8ccf952acc73e17522846bc1eb41498e840d637e519ddcca7dbc7671, d14e08374fc7197d6a0de468c968ae8ba3aadbf9315476fd39071831f5923662, 057eed1fd48c238491b8ea06b9b5bf85a5d4c9275dd3f6183e0e6b01730cc2ba, e491352788e56ca4603acc411ffe1a49fefd76ed8b163af86cf5ee5f4c38645b, 40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7, 97b883cd8a2b7f49f90d5d39c981cf6e110cf1f1c64427a28a6d58ec88c43657, context: {ledger_id: “participant1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”, instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, application_id: “foobar”, read_as: “List(bob::1220649b43530aabe92d941de529d021b18ac09cefd0880f5df928a47effd80f40c8)”, act_as: “List(alice::1220649b43530aabe92d941de529d021b18ac09cefd0880f5df928a47effd80f40c8)”}
07-06-2022 11:36:11.671 [http-json-ledger-api-akka.actor.default-dispatcher-15] INFO com.daml.http.Endpoints - Responding to client with HTTP 400 Bad Request, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”}

i checked the package IDs loaded and it is not there

CO
cocreature
Jun 2022

Looking at your earlier logs, I don’t see the DAR actually uploaded: participant1.dars.list() shows only the builtin AdminWorkflows not your own DAR.

Maybe try uploading via daml ledger upload-dar to participant 1.

BE
Bernardo
Jun 2022

I manage to upload the dar into participant1 and now i can see it in JSON API,

JSON API:

But now i get this error:

GA
Gary_Verhaegen
Jun 2022

Hi @Bernardo,

That error is not actually surprising at that point. Let’s go back a step: when you tell the domain to upload a DAR to all participants, the DAR does not get added to participant1. But when you explicitly upload to participant1, that works, so participant1 itself is not broken.

This suggests that your first issue is that the domain and the participants are somehow not talking to each other, which seems to be corroborated by this new error message. I’m also a bit surprised that the result to your participants.all.dars.upload command is empty. I’d somehow expect a map of participant to result there.

I’m not familiar enough with Canton to help with debugging this but I think that’s the first thing you should look into. (Moving forward, we’ve still not solved the daml start issue either, but one thing at a time.)

BE
Bernardo
Jun 2022
Gary_Verhaegen:

when you tell the domain to upload a DAR to all participants, the DAR does not get added to participant1. But when you explicitly upload to participant1, that works, so participant1 itself is not broken.

I updated the domain conf file, and added both participants:

canton {
domains {
mydomain {
  storage.type = memory
  admin-api {
    port = 10017
    address = 192.168.61.129 // is the default value if omitted
  }
  public-api {
    port = 10018
    address = 192.168.61.129 // is the default value if omitted
  }
 }
}

remote-participants {
 participant1 {
  admin-api {
    port = 5012
    address = 192.168.61.128
  }
  ledger-api {
    port = 5011
    address = 192.168.61.128
  }
 }
}

remote-participants {
 participant2 {
  admin-api {
    port = 5012
    address = 192.168.61.130
  }
  ledger-api {
    port = 5011
    address = 192.168.61.130
   }
  }
 }
}

This is why now i am able to upload the dar and it is visible to participant1 and 2

Gary_Verhaegen:

(Moving forward, we’ve still not solved the daml start issue either, but one thing at a time.)

I just use the daml start --script-option --output-file=parties.json to get the Party ids, in order to create contracts with json api. I need the Party id for alice and bob that are specified in that file.

Thank you for your time, hope Moritz can help me

GA
Gary_Verhaegen
Jun 2022
Bernardo:

Thank you for your time, hope Moritz can help me

It’s not entirely clear what problem you’re now facing. You tell us the dar upload is now working; can you explain what you still need help with? What error are you now seeing?

BE
Bernardo
Jun 2022

The dar is uploaded to participant1 but when i try to create contracts with participant1 using JSON API i get 404 error

GA
Gary_Verhaegen
Jun 2022

That’s a weird error essage, but let’s assume for a second it may be related to the daml start issue. When you run daml start, by default it will run a local sandbox and run its commands against that. I’m not seeing anything in your daml.yaml or your CLI arguments to overwrite that default behaviour. This means that the parties you have created with your script get created on the sandbox created by daml start, and not on the participants in your domain.

In order to create the parties, you’ll need to run the script against the appropriate participant (I imagine that, as you have two participants, you probably want to create different parties in each one). You can do that with the daml script command, which, unlike daml start, does not start its own sandbox but instead runs against the participant you point it to (run daml script --help for details). You’ll need to first compile the DAR containing your script with daml build, then run something like:

daml script --dar PATH_TO_DAR \
            --ledger-host 192.168.61.128 \
            --ledger-port 5011 \
            --output-file PARTIES_PART1.json \
            --script-name module:function \
            --input-file INPUT_PART1.json

with uppercase things changed to appropriate values (you may or may not need an input-file, depending on the details of your script).

BE
Bernardo
Jun 2022

It worked! Thank you very much! :grinning:

The correct party id was the participant’s!

GA
Gary_Verhaegen
Jun 2022

Happy to help!

Would you mind marking the question as resolved? You can always open a new thread if you have further questions down the line.

← Back to Discussions