Bindings Structure
The tool writes the files in the specified output directory with the following structure. Assuming you have a <service-name>.did file, <service-name> is used for the generated files.
Note: The generated code imports elements from
@icp-sdk/core. You must install it, see js.icp.build/core.
<service-name>.ts
Section titled “<service-name>.ts”This file contains the TypeScript wrapper for the Candid JS bindings generated in declarations/<service-name>.did.js. It offers a more idiomatic and type-safe TypeScript interface over the Candid JS bindings.
Set the output.actor.disabled option to true to skip generating this file.
The generated file exposes:
- The types, that is the TypeScript representation of the Candid types.
- The
<service-name>Interfacetype, that is the TypeScript interface for the service. - The
<service-name>class, that is the TypeScript class for the service. - The
createActorfunction, that creates a new instance of the actor.
This section contains the TypeScript representation of the Candid types. It contains all the types that are defined as Candid types in the .did file. To make the generated types more idiomatic, some types are transformed into more TypeScript-friendly types.
Options
Section titled “Options”Candid options are represented as a union of the inner option type and null:
type MyType = opt text;type MyType = string | null;Nested/Recursive Options
Section titled “Nested/Recursive Options”Nested or recursive options are represented as union of the Some and None types, where Some and None are defined as:
interface Some<T> { __kind__: "Some"; value: T;}interface None { __kind__: "None";}Nested
Section titled “Nested”type MyType = opt opt text;type MyType2 = opt opt opt text;type MyType = Some<string | null> | None;type MyType2 = Some<Some<string | null> | None> | None;Recursive
Section titled “Recursive”type A = B;type B = opt A;type A = B;type B = Some<A> | NoneRecord Fields with Options
Section titled “Record Fields with Options”Record fields that have an option type are optional fields in the TypeScript type:
type MyType = record { my_field : opt text;}type MyType = { my_field?: string;};Variants
Section titled “Variants”Candid variants without type parameters are represented as TypeScript enums:
type MyType = variant { A; B;}enum MyType { A, B,}Variants with Types
Section titled “Variants with Types”Variants that contain types in their fields are represented as TypeScript unions:
type MyType = variant { A : text; B; C : record { my_field : text; };}type MyType = | { __kind__: "A"; A: string } | { __kind__: "B"; B: null } | { __kind__: "C"; C: { my_field: string } };<service-name>Interface type
Section titled “<service-name>Interface type”This type is the TypeScript interface for the service. It contains all the methods that are defined in the Candid service in the .did file.
For example, a Candid service will be represented as:
service : () -> { greet : (name : text) -> text;};interface helloWorldInterface = { greet: (name: string) => Promise<string>;};<service-name> class
Section titled “<service-name> class”This class implements the <service-name>Interface type. It can be instantiated with the createActor function.
For example, a Candid service will be represented as:
service : () -> { greet : (name : text) -> text;};class HelloWorld implements helloWorldInterface { constructor( private actor: ActorSubclass<_SERVICE>, ) {} async greet(arg0: string): Promise<string> { const result = await this.actor.greet(arg0); return result; }}Where the _SERVICE type is imported from the declarations/<service-name>.did.d.ts file and the ActorSubclass type is imported from the @icp-sdk/core/agent module.
createActor function
Section titled “createActor function”Creates an instance of the <service-name> class.
Here’s an example of how to use the generated client:
import { createActor } from "./bindings/hello_world";
const actor = createActor("your-canister-id");const greeting = await actor.greet("World");The signature of the createActor function is:
interface CreateActorOptions { agent?: Agent; agentOptions?: HttpAgentOptions; actorOptions?: ActorConfig;}
function createActor(canisterId: string, options: CreateActorOptions = {}): <service-name>Interface;If both the agent and agentOptions are provided, the agentOptions will be ignored and the agent will be used. Otherwise, a new HttpAgent will be created using the agentOptions if provided.
If provided, the actorOptions will be passed to the Actor.createActor function. Otherwise, the default options will be used.
declarations/
Section titled “declarations/”This folder contains the actual Candid JS bindings. It generates the same bindings that the dfx generate command was generating.
See the Migrating page for more information on how to migrate from dfx generate.
declarations/<service-name>.did.d.ts
Section titled “declarations/<service-name>.did.d.ts”This file is used in TypeScript projects to type the Candid JS bindings generated in declarations/<service-name>.did.js.
declarations/<service-name>.did.js
Section titled “declarations/<service-name>.did.js”This file contains the actual Candid JS bindings, that allow encoding and decoding JS objects to and from Candid.
Optional files
Section titled “Optional files”<service-name>.d.ts
Section titled “<service-name>.d.ts”This file contains the same TypeScript types as <service-name>.ts. It is typically used to add to LLMs’ contexts’ to give knowledge about what types are available in the service. Set the output.actor.interfaceFile option to true to generate this file.