Canister declarations
The DFX auto-generated bindings for canisters had some issues in versions of DFX lower than 0.16.0
that made the developer experience with PicJS less than ideal. If you are using DFX v0.16.0
or higher then you can ignore this guide.
There are four files generated by DFX for a canister. To use a counter
canister as an example:
-
counter.did.js
- Exports the canister's Candid as a JavaScript object. TheidlFactory
andinit
exports in this file are not included in thecounter.did.d.ts
file.export const idlFactory = ({ IDL }) => {
const Counter = IDL.Service({
// redacted...
});
return Counter;
};
export const init = ({ IDL }) => {
return [IDL.Nat];
}; -
counter.did.d.ts
- Exports the canister's Candid as a TypeScript interface. This file is missing theidlFactory
andinit
exports that are present in thecounter.did.js
file.import type { Principal } from '@dfinity/principal';
import type { ActorMethod } from '@dfinity/agent';
export interface Counter {
// redacted...
}
export interface _SERVICE extends Counter {} -
index.d.ts
- Exports TypeScript interfaces for actor creation utilities. This file re-exports theidlFactory
, but not theinit
declarations fromclock.did.ts
.import type {
ActorSubclass,
HttpAgentOptions,
ActorConfig,
Agent,
} from '@dfinity/agent';
import type { Principal } from '@dfinity/principal';
import type { IDL } from '@dfinity/candid';
import { _SERVICE } from './counter.did';
export declare const idlFactory: IDL.InterfaceFactory;
export declare const canisterId: string;
export declare interface CreateActorOptions {
// redacted...
}
export declare const createActor: (
canisterId: string | Principal,
options?: CreateActorOptions,
) => ActorSubclass<_SERVICE>;
export declare const counter: ActorSubclass<_SERVICE>; -
index.js
- Exports TypeScript interfaces for actor creation utilities. This file re-exports theidlFactory
, but not theinit
declarations fromclock.did.js
and also exports an auto-created canister actor which will throw exceptions outside of the browser due towindow.location
missing.import { Actor, HttpAgent } from '@dfinity/agent';
import { idlFactory } from './counter.did.js';
export { idlFactory } from './counter.did.js';
export const canisterId =
process.env.CANISTER_ID_COUNTER || process.env.COUNTER_CANISTER_ID;
export const createActor = (canisterId, options = {}) => {
// redacted...
};
export const counter = createActor(canisterId);
To summarize the problems:
index.js
andindex.d.ts
are missing theinit
export and also export an auto-created actor that breaks outside of the browser.counter.did.js
andcounter.did.d.ts
are missing theinit
andidlFactory
exports.
Fixes for these issues are already merged into Candid, but they need to be released and included in DFX before we can leverage them. To work around these issues for now, we can add two new files to export the missing items:
-
index.js
export { idlFactory, init } from '../../declarations/counter.did';
-
index.d.ts
import { IDL } from '@dfinity/candid';
import { Actor } from '@hadronous/pic';
import { _SERVICE } from '../../declarations/counter.did';
export declare const idlFactory: IDL.InterfaceFactory;
export declare const init: ({ IDL }: { IDL: IDL }) => IDL.Type[];