Call daml script from another app

Hello everyone,

Given an app running in a separate machine (spring-boot java app in this case), what is the best way for this app to call a daml script to execute operations in a ledger running remotely.
Is it necessary to have the dar file within the spring-boot app, or is there a better way to do it?
Thanks

2 Likes

Hi @joaogaspar Welcome to the Daml Forum!

That is a great question, one that I think of frequently and have been looking for an answer to. Currently I can action remote activities using Bash scripting, but I would like to do something neater and more integrated, but not using Java.

In case you have not seen this comprehensive collection of Daml learning materials by @anthony, it is well worth a visit, here.

1 Like

There is no API for running a Daml Script so atm your best option is to shell out to daml script and run it that way. That requires you to pass the path to the DAR as an argument so you need to include it somehow.

2 Likes

Are there any plans for a Daml Script API?

I would posit that most use cases will involve a Daml App & UI on a Ledger but there will be some who want to action things as a process, either System-driven (init.d/rc.d/services) or on a case-by-case scripting basis.

Scripting is fine, just not neat :thinking:

2 Likes

I’m not aware of a roadmap item to build up a “Script API”. I would assume that if you are already in a programming language, you could do what you want through either the JSON API or the gRPC API, and offering a third alternative seems a bit redundant.

Would you mind describing in a bit more details how you would expect a “Script API” to work? What would you do with it and how would you use it?

3 Likes

I can imagine something like the trigger service, even both merged together.
In the end the goal would be to run a set of instructions coded in daml from a ledger client and not have to do it with another language.
The main advantage here would be not having the need to target the dar file, but this api instead. Not knowing what constraints it may raise but i think it could be useful.

1 Like

What @joaogaspar posted below/above seems like a good compromise. Have a Script/Trigger API that you demand to action an event of a particular, nominated .DAR, rather than directly scripting a .DAR to do something.

I just wrote a pseudocode string as an example and realised that it was replicating a `daml script --commmand’ almost exclusively. Perhaps the functionality I seek is inherent in the existing Daml codebase but still above my current knowledge threshold.

I’ll do some more RTFineM :grinning:

There’s a strong design tension here that makes a Script API difficult to refine into a design plan:

Daml Script can’t do anything that you can’t do directly with the gRPC API or JSON API; this is straightforwardly demonstrated by the implementation of Daml Script doing everything by these APIs.

The benefit of Daml Script, for its intended use cases, is that you are specifying everything in Daml. But a general-purpose API necessarily has all these…options. The more you want to make the API useful for general-purpose client access, the more options you have to add, and the more it mutates into a facsimile of one of our other APIs, just more indirect and less efficient.

To put it another way, at the heart of a Script-oriented API must be literally what you have said, specifying instructions “coded in daml”, and “not [be able] to do it with another language”.

That said, there are interesting potential areas of inquiry regarding both invoking scripts, such as by

  1. leveraging the daml-script/runner/ library in the main daml repo, and
  2. potentially extending that functionality by making it possible to supply Daml-value arguments to scripts, either via a codegen’s primitive and record conversion support or something more language-native like the TypedValueGenerators I wrote for unit-testing purposes.

But to rewind a bit,

There is no reasonable Script-related architecture that I can imagine that doesn’t require a DAR as input at some step. Either the script has to be compiled to a DAR, or the process that evaluates the script must include compiling, and assuming it refers to the “main” contract code, that code must be in DAR form. So any script API would necessarily entail working with DARs as well.

@quidagis Nothing stable/supported but the code in daml-script/runner/ is where I’d start. (A Daml script engine requires a Daml evaluator, which means you’re in Scala unless you wish to reimplement everything. At least as far as implementation of an API “service” goes.)

1 Like

Which is what I realised, it would be unnecessary duplication.

Thank you for that, and for the contextually relevant answer :+1:t2:

Based on your description I think you could actually build some proof-of-concept-quality demo of what you want by wrapping daml script behind a web server.

Your web server would need an endpoint that accepts, in some form:

  • $TOKEN: A token. If you’re going to interact with a Daml ledger, you need a token.
  • $SCRIPT: A fully-qualified name for a script.
  • $INPUT: A JSON blob.

Upon receiving a request, the server would do something like:

daml script --dar my-hardcoded-dar-on-the-server.dar \
            --script-name "$SCRIPT" \
            --ledger-host "hardocded.example.com" \
            --ledger-port 6865 \
            --input-file <(echo "$INPUT") \
            --access-token-file <(echo "$TOKEN") \
            --output-file resp.json

and then return the contents of resp.json as its response.

If you’re feeling brave, you could even try to build that on top of the Daml Script codebase so you can invoke the script directly in-process, rather than shell out to the Daml Assistant. That’d have to be in Scala, as @Stephen mentioned.

Of course, I feel compelled to note:

WE WOULD NOT SUPPORT ANY OF THAT. PROCEED AT YOUR OWN RISKS.

1 Like

Thank you @Gary_Verhaegen for the very interesting & edgy solution. I will need to unpack that and walk through the Docs carefully. What a project that would be :+1:t2: :thinking: