DAML SDK 1.7.0 has been released on November 11th 2020. You can install it using:
daml install latest
If you're using the DAML Triggers Early Access you'll need to migrate to the new API. No other mandatory changes are required for this release but other impacts and migrations are detailed below.
daml start can now perform code generation, and has a quick-reload feature for fast iterative app developmentDA.Generics. If you receive such warnings, it is recommended that you move off them. If you are getting unexpected warnings, or don’t know how to migrate, please get in touch with us via the public forum or support.digitalasset.com (for registered users).Background
With Release 1.6 work started to clarify the DAML stack in many respects: What it consists of, what state different pieces are in, and what stability and compatibility guarantees users can expect. However, the ecosystem overview page highlighted that there was a lack of good terminology of the sets of components users needed to either establish a DAML network, or to connect to a DAML network. Previously the label “SDK” was sometimes used to refer to the latter, but that was inaccurate since the SDK only contains components intended to be used at development time. With release 1.7 this has been tidied up with clearer terminology for different layers of the stack. DAML Connect describes all those pieces that are needed to connect to a DAML network:
daml codegen commandsSpecific Changes
The ecosystem overview docs page has been improved, and naming has been adjusted throughout docs and artifacts to incorporate these changes.
Impact and Migration
This change only affects documentation and help text. There are no API changes.
Background
The DAML Ledger API has supported multi-party transaction subscriptions for a long time, but until now, the runtime components like JSON API, and DAML Script and REPL were only able to query as a single party. As a first step towards enhancing DAML’s capabilities in sharing data in more flexible ways than the observer concept, the runtime components have now gained features to query contracts on behalf of multiple parties at the same time. Since read-access via the JSON API is controlled using JWTs, any client of the JSON API, including the JavaScript client libraries, can profit from these improvements provided the token issuer is able to issue appropriate tokens.
Specific Changes
readAs field. In queries, contracts known to any of the known parties will be returned. In command submissions, the readAs field is ignored. actAs is still limited to a single party.
readAs party, and no actAs party set for command submission endpoints. When working with unauthenticated ledgers, this could lead to successful command submission without an actAs party set. This bug has been fixed as part of this change. If you were previously exploiting this bug during development, please move the submitting party from readAs to actAs.query, queryContractId, and queryContractKey now accept multiple parties using the IsParties abstraction used by signatory, observer, and other fields. Specifically this means they accept single parties, lists of parties, and sets of parties interchangeably. They will return all contracts for which any of the given parties is a stakeholder.Impact and Migration
As mentioned above, a bug was fixed in which a command submission could be successful via the JSON API if only the readAs field in the JWT was set, and the underlying Ledger API was running in unauthenticated mode. This is no longer possible. The submitting party has to be set in the actAs field.
Background
daml start is the primary command allowing quick testing of a DAML application. It compiles DAML contracts, starts up a Sandbox and a Navigator, and runs initialization scripts. However, it didn’t run code-generation, nor did it have any functionality for re-building and deploying after a change, requiring developers to manually shut it down, re-generate code, and restart. With this release, that manual and error-prone process has been replaced with automatic refreshes including codegen.
Note that if you use Navigator, you might still want to do a full restart to clear old contracts and packages.
Specific Changes
You can now press 'r' (or 'r' + 'Enter' on Windows) in the terminal where daml start is running to rebuild the DAR package and generate JavaScript/Java/Scala bindings and upload the new package to the Sandbox. This frees the user from killing and restarting daml start.
The daml start now runs all the code generators specified in the daml.yaml project configuration file under the codegen stanza. This frees the user from having to do so manually on every change to the DAML model.
For example, instead of running the JavaScript codegen manually as part of the create-daml-app, it is now included in the daml.yaml.
Before: Manual run of
daml codegen js .daml/dist/create-daml-app-0.1.0.dar -o daml.js
After: stanza in daml.yaml
Impact and Migration
This is a purely additive change.
Background
The DAML API of Triggers has been brought further inline with those of DAML Script and REPL, at the same time allowing for more efficient implementation of high-level triggers under the hood. Before, all the information consumable by the trigger rule, initialization, and update functions was passed in as function arguments. With this iteration, state, active contracts, and time are accessible using actions (using <- notation) instead.
Specific Changes
updateState, rule, and initialize functions no longer accept an ACS argument; instead, they must use the query action to query the active contract set, similar to the same function in DAML Script. See issue #7632.TriggerA action now has functions to get, put and modify user defined state.Time argument was removed from the trigger rule function; instead, it can be fetched within the TriggerA do block by getTime, as with Update and Script.Map CommandId [Command] argument has been removed from high-level trigger rule functions; instead, the current commands-in-flight can be retrieved with the new getCommandsInFlight function. See issue #7600.initialize is now a TriggerInitializeA action, which is able to query the ledger using query and related functions, and returns the initial state.updateState function now takes just a message and returns a TriggerStateA which allows querying the ledger using query and related functions, and modifying state using the get, put, and modify functions. See issue #7621.queryContractId, for looking up a contract by ID, and queryContractKey for looking one up by key. See issue #7726.Impact and Migration
1. To migrate an existing initialize function acs -> expr, write a do block with query taking the place of any getContracts occurrences. For example
For triggers without custom state (ie s == ()), pure () is the right expression for initialize.
2. To migrate an existing updateState function, deal with ACS access as in 1. In addition, replace the state argument by calls with a call to modify.
For triggers without custom state (ie s == ()), \msg -> pure () is the right expression for initialize.
3. To migrate an existing rule function, deal with ACS access as in 1., replace the state argument with a call to get, and in addition replace time and commands-in-flight access using the new accessor functions.
time, commandsInFlight, and state are each optional; if they are not used, the lines that “get” them may be removed.
Background
Since version 1.6 the JSON API and JavaScript client libraries have had support for stream requests with multiple keys or queries. As of 1.7, this functionality is also available in the React Hooks, allowing for more efficient binding of ledger data to UI elements.
Specific Changes
useStreamQueries and useStreamFetchByKeys hooks in @daml/react mapping to, respectively, streamQueries and streamFetchByKeys in @daml/ledger.Impact and Migration
The change is fully backwards compatible as the old singular functions are merely deprecated, not removed. The below describes the upgrade path for the new multi-query versions.
Upgrading useStreamQuery is straightforward: the query factory remains optional, but if specified it should return an array of queries instead of a single query. The array may be empty, which will return all contracts for that template, similar to not passing in a query factory. The return values of useStreamQuery and useStreamQueries have the same type.
Upgrading useStreamFetchByKey is only slightly more involved as the return type of useStreamFetchByKeys is different, called FetchByKeysResult instead of the existing FetchResult. FetchByKeysResult differs from FetchResult in that it contains a contracts field with an array of contracts instead of a singular contract field. It differs from QueryResult in that each element of the returned array can also be null, if there is no corresponding active contract. Call sites can be updated as follows:
daml ledger list-parties command can now query the ledger for known parties via the HTTP JSON API instead of the gRPC API. This requires setting the --json-api flag.--query-store-jdbc-config-env./livez and /readyz health check endpoints for easier integration with k8s and other schedulers.useStreamQueries and useStreamFetchByKeys as well as their (deprecated) singular counterparts now accept an optional closeHandler callback, which will be called if the underlying WebSocket connection get closed due to an error or because close was called.close event as an error. However, there are legitimate cases for the connection to be closed (e.g. the component has been unmounted). The default behaviour will now be to log only unexpected disconnects and be silent on deliberate connection closes. This can be customized using the closeHandler.reconnectThreshold can now be configured through the LedgerProps of the React wrapper.DA.Date type now has Enum and Bounded instances allowing the use of ranges. Eg-- Create a list of all Sundays in 2020[date 2020 Jan 5, date 2020 Jan 12 .. date 2020 Dec 31]daml build.useStreamFetchByKeys hook to sometimes report a "ready" state (i.e. loading: false) even though the underlying connection had not yet been fully established.daml ledger upload-dar now exits with a non-zero exit code on failures and no longer prints "DAR upload succeeded" in error cases. This was a regression.daml.commands.<party_name>.input_buffer_sizedaml.commands.<party_name>.input_buffer_saturationdaml.commands.<party_name>.max_in_flight_sizedaml.commands.<party_name>.max_in_flight_saturationdaml.commands.submissions_runningdaml.execution.total_runningdaml.execution.engine_running--ledger-clock-granularity option now takes a time duration (e.g. "10s" or "5m"), rather than an integer number of milliseconds.skip-dar-upload. See docs.ResourceOwner type is now parameterized by a Context, which is filled in by the corresponding Context class in the ledger-resources dependency. This allows us to pass extra information through resource acquisition.daml.kvutils.committer.package_upload.validate_timer to track package validation time.ParticipantConfig and the default value is now set to 2 minutes. See issue #6880.