Unfortunately we do not currently support interactions with HTML forms directly. The issue here is that HTML <form>
send data in a format called, appropriately, “form data” (formally application/x-www-form-urlencoded
), which is not a format we currently support. At this point in time, your only option to interact with a Daml ledger from a browser is to go through the JSON API, which requires JSON data. And the only way to generate JSON requests from a browser is with JavaScript.
We could remove the React/Semantic-UI bits of the create-daml-app template, but it would still need to use JavaScript to manage interactions with the JSON API.
(Yes, sandbox is an in-memory, ephemeral ledger that exposes the same API as other Daml ledgers, so you can develop your code against it and then later on deploy the same code against a production, persistent one.)
My point was that, if you are comfortable with JavaScript (and HTML, and CSS, and the DOM API) but not with React, you could choose to not use React and therefore not use @daml/react
while still benefitting from the codegen and still using @daml/types
and @daml/ledger
. However, if you are not familiar with JS, CSS, HTML & DOM (+ JS build tooling, I suppose) I’m afraid I don’t have a good answer for you at the moment. Web development has become awfully complicated these days.
The best I can give you at the moment (and I’m well aware it’s not much, so apologies for that) is an encouragement to read through our getting started guide if you haven’t already. It is using slightly different tools than daml-ui-template
(Semantic UI instead of Material UI, npm instead of yarn) but the general principles are the same, and there is a lot more documentation. The create-daml-app
documentation is also kept up-to-date, and testing that the template works as expected is part of our release process, so you are much less likely to encounter unexpected issues than with daml-template-ui
, which does not seem to be actively maintained. (It’s currently 5 Daml releases late.)
Unfortunately the answer here is not straightforward. localhost
is a fluent concept, as it literally means “the current machine”. So you can only be on localhost
as seen from the same machine, where “machine” may not quite mean what you’d think it means.
Guessing a little bit, I am assuming that you have opened a terminal and typed daml sandbox
(or daml start
), so you have a sandbox running on your macOS “host” machine. At startup, the sandbox should output which port it’s listening to; something like:
INFO: Listening on localhost:6865 over plain text.
This is not what we’re interested in here. What you need to give to nginx
is the hostname and port of the JSON API. If you’ve run daml start
, it should automatically start (though that may depend on your daml.yaml
); if so, it should print something like:
12:49:43.492 [http-json-ledger-api-akka.actor.default-dispatcher-7] INFO com.daml.http.Main$ - Started server: ServerBinding(/127.0.0.1:7575)
This is the one we want. However, 127.0.0.1
is just as relative as localhost
so that may not help us much. In particular, if you run nginx
within Docker, things get a bit hairy. Docker only runs on Linux, which means that on macOS Docker has to run in a virtual machine. There are essentially two easy ways to get Docker up and running:
- Docker for Mac, which is imo a terrible idea but the one promoted by Docker, so you’re probably running that.
docker-machine
, which is a portable (non-macOS-specific) way to handle running Docker servers “outside” your local machine.
In both cases Docker will run in a Linux virtual machine; the main difference is that Docker for Mac tries to hide that fact and creates a very leaky abstraction that results in all sorts of hard-to-debug corner cases. Either way, the result will be that you have three networks at play here, and thus three possible meanings for localhost
(== 127.0.0.1
):
- The host, macOS machine.
- The Linux VM.
- The Docker container.
Visibility across these networks is not complete. Typically, 1 can see 2 but 2 cannot see 1, and 2 can see 3 but 3 cannot see 2 (or 1). The issue you’ll have here is that your nginx instance runs in 3 but your JSON API runs in 1, and therefore redirecting traffic from nginx (3) to JSON API (1) is not possible.
There are two workable options here. The first is to run the sandbox and JSON API as Docker containers too. That way, they’d be in the same network as nginx and therefore visible to it. To achieve that, you could use the (development-only, definitely not supported for production) daml-sdk
image we provide. This would look something like:
FROM digitalasset/daml-sdk:1.12.0
USER root
RUN mkdir /app
COPY .daml/dist/ /app/
RUN chown -R daml:daml /app
USER daml
Build this with docker build -t my-daml .
(from the root of your project), and then run it twice with commands along the lines of:
docker run --name sandbox my-daml daml sandbox --address 0.0.0.0 --ledgerid ledger /app/my.dar
to start a sandbox with your DAR file (i.e. your compiled daml code) loaded, and
docker run --name json --link sandbox my-daml daml json-api --ledger-host sandbox --ledger-port 6865 --http-port 7575 --address 0.0.0.0
to run the JSON API. And then you can run your nginx machine with the --link json
option such that, from within the nginx container, the hostname of the JSON API is json
and your configuration becomes:
...
location /v1 {
proxy_pass http://json:7575;
}
location /v1/stream {
proxy_pass http://json:7575;
...
Hope that helps.