- Overview
- Tutorials
- Getting started
- Get started with Canton and the JSON Ledger API
- Get Started with Canton, the JSON Ledger API, and TypeScript
- Get started with Canton Network App Dev Quickstart
- Get started with smart contract development
- Basic contracts
- Test templates using Daml scripts
- Build the Daml Archive (.dar) file
- Data types
- Transform contracts using choices
- Add constraints to a contract
- Parties and authority
- Compose choices
- Handle exceptions
- Work with dependencies
- Functional programming 101
- The Daml standard library
- Test Daml contracts
- Next steps
- Application development
- Getting started
- Development how-tos
- Component how-tos
- Explanations
- References
- Application development
- Smart contract development
- Daml language cheat sheet
- Daml language reference
- Daml standard library
- DA.Action.State.Class
- DA.Action.State
- DA.Action
- DA.Assert
- DA.Bifunctor
- DA.Crypto.Text
- DA.Date
- DA.Either
- DA.Exception
- DA.Fail
- DA.Foldable
- DA.Functor
- DA.Internal.Interface.AnyView.Types
- DA.Internal.Interface.AnyView
- DA.List.BuiltinOrder
- DA.List.Total
- DA.List
- DA.Logic
- DA.Map
- DA.Math
- DA.Monoid
- DA.NonEmpty.Types
- DA.NonEmpty
- DA.Numeric
- DA.Optional
- DA.Record
- DA.Semigroup
- DA.Set
- DA.Stack
- DA.Text
- DA.TextMap
- DA.Time
- DA.Traversable
- DA.Tuple
- DA.Validation
- GHC.Show.Text
- GHC.Tuple.Check
- Prelude
- Smart contract upgrading reference
- Glossary of concepts
Daml Codegen for JavaScript¶
Use the Daml Codegen for JavaScript (daml codegen js
) to generate JavaScript/TypeScript code representing all Daml data types
defined in a Daml Archive (.dar) file.
The generated code makes it easier to construct types and work with JSON when using the JSON Ledger API.
See Get started with Canton and the JSON Ledger API for details on how to use the generated code to interact with JSON Ledger API. See the sections below for guidance on setting up and invoking the codegen.
Install¶
Install the Daml Codegen for JavaScript by installing the Daml Assistant.
Configure¶
To configure the Daml Codegen, choose one of the two following methods:
Command line configuration: Specify all settings directly in the command line.
Project file configuration: Define all settings in the daml.yaml file.
Command line configuration¶
To view all available command line configuration options for Daml Codegen for JavaScript, run daml codegen js --help
in your terminal:
DAR-FILES DAR files to generate TypeScript bindings for
-o DIR Output directory for the generated packages
-s SCOPE The NPM scope name for the generated packages;
defaults to daml.js
-h,--help Show this help text
Project file configuration¶
Specify the above settings in the codegen
element of the Daml project file daml.yaml
.
Here is an example:
sdk-version: 3.3.0-snapshot.20250507.0
name: quickstart
source: daml
init-script: Main:initialize
parties:
- Alice
- Bob
- USD_Bank
- EUR_Bank
version: 0.0.1
exposed-modules:
- Main
dependencies:
- daml-prim
- daml-stdlib
codegen:
js:
output-directory: ui/daml.js
npm-scope: daml.js
Operate¶
Run the Daml Codegen using project file configuration with:
$ daml codegen js
or using command line configuration with:
$ daml codegen js ./.daml/dist/quickstart-0.0.1.dar -o ui/daml.js -s daml.js
References¶
Generated JavaScript/TypeScript code¶
Daml primitives to TypeScript¶
Daml built-in types are translated to the following equivalent types in TypeScript. The TypeScript equivalents of the primitive Daml types are provided by the @daml/types.
Interfaces:
interface Template<T extends object, K = unknown, I extends string = string>
interface Choice<T extends object, C, R, K = unknown>
Types:
Daml |
TypeScript |
TypeScript definition |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note
The types given in the TypeScript column are defined in @daml/types.
Note
For n-tuples where n ≥ 3, representation is analogous with the pair case (the last line of the table).
Note
The TypeScript types Time
, Decimal
, Numeric
and Int
all alias to string
. These choices relate to
the avoidance of precision loss under serialization over the JSON Ledger API.
Note
The TypeScript definition of type Optional<τ>
in the above table might look complicated. It accounts for differences in the encoding of optional values when nested versus when they are not (i.e. “top-level”). For example, null
and "foo"
are two possible values of Optional<Text>
whereas, []
and ["foo"]
are two possible values of type Optional<Optional<Text>>
(null
is another possible value, [null]
is not).
Generated TypeScript mappings¶
The mappings from user-defined data types in Daml to TypeScript are best explained by example.
Records (a.k.a. product types)¶
In Daml, we might model a person like this.
1data Person =
2 Person with
3 name: Text
4 party: Party
5 age: Int
Given the above definition, the generated TypeScript code will be as follows.
1type Person = {
2 name: string;
3 party: damlTypes.Party;
4 age: damlTypes.Int;
5}
Variants (a.k.a. sum types)¶
This is a Daml type for a language of additive expressions.
1data Expr a =
2 Lit a
3 | Var Text
4 | Add (Expr a, Expr a)
In TypeScript, it is represented as a discriminated union.
1type Expr<a> =
2 | { tag: 'Lit'; value: a }
3 | { tag: 'Var'; value: string }
4 | { tag: 'Add'; value: Tuple2<Expr<a>, Expr<a>> }
Sum of products¶
Let’s slightly modify the Expr a
type of the last section into the following.
1data Expr a =
2 Lit a
3 | Var Text
4 | Add {lhs: Expr a, rhs: Expr a}
Compared to the earlier definition, the Add
case is now in terms of a record with fields lhs
and rhs
. This renders in TypeScript like so.
1type Expr<a> =
2 | { tag: 'Lit'; value: a }
3 | { tag: 'Var'; value: string }
4 | { tag: 'Add'; value: Expr.Add<a> }
5
6namespace Expr {
7 type Add<a> = {
8 lhs: Expr<a>;
9 rhs: Expr<a>;
10 }
11}
Note how the definition of the Add
case has given rise to a record type definition Expr.Add
.
Enums¶
Given a Daml enumeration like this,
1data Color = Red | Blue | Yellow
the generated TypeScript will consist of a type declaration and the definition of an associated companion object.
1type Color = 'Red' | 'Blue' | 'Yellow'
2
3const Color:
4 damlTypes.Serializable<Color> & {
5 }
6& { readonly keys: Color[] } & { readonly [e in Color]: e };
Templates and Choices¶
Here is a Daml template of a basic ‘IOU’ contract.
1template Iou
2 with
3 issuer: Party
4 owner: Party
5 currency: Text
6 amount: Decimal
7 where
8 signatory issuer
9 choice Transfer: ContractId Iou
10 with
11 newOwner: Party
12 controller owner
13 do
14 create this with owner = newOwner
The daml codegen js
command generates types for each of the choices defined on the template as well as the template itself.
1type Transfer = {
2 newOwner: damlTypes.Party;
3}
4
5type Iou = {
6 issuer: damlTypes.Party;
7 owner: damlTypes.Party;
8 currency: string;
9 amount: damlTypes.Numeric;
10}
Each template results in the generation of an interface and a companion object. Here, is a schematic of the one
generated from the Iou
template [1], [2].
1 interface IouInterface {
2 Archive: damlTypes.Choice<Iou, DA.Internal.Template.Archive, {}, undefined> & damlTypes.ChoiceFrom<damlTypes.Template<Iou, undefined>>;
3 Transfer: damlTypes.Choice<Iou, Transfer, damlTypes.ContractId<Iou>, undefined> & damlTypes.ChoiceFrom<damlTypes.Template<Iou, undefined>>;
4 }
5
6 const Iou:
7 damlTypes.Template<Iou, undefined, '<template_id>'> &
8 damlTypes.ToInterface<Iou, never> &
9 IouInterface;
See the Use contracts and transactions in JavaScript for details on how to use generated code to interact with the JSON Ledger API.