CandidAdapter
CandidAdapter provides low-level utilities for fetching Candid definitions from canisters and compiling them to IDL factories. Use it when you need fine-grained control over Candid handling.
Overview
Section titled “Overview”The adapter supports multiple methods for obtaining Candid:
- Canister Metadata — Query the canister’s
__get_candid_interface_tmp_hackmethod - didjs Canister — Use the didjs canister to compile Candid to JavaScript
- Local Parser — Use the optional
@ic-reactor/parserfor offline compilation
import { CandidAdapter } from "@ic-reactor/candid"
const adapter = new CandidAdapter({ clientManager })
// Fetch and parse in one callconst { idlFactory } = await adapter.getCandidDefinition( "ryjl3-tyaaa-aaaaa-aaaba-cai")Import
Section titled “Import”import { CandidAdapter } from "@ic-reactor/candid"Constructor
Section titled “Constructor”new CandidAdapter(config: CandidAdapterParameters)Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
clientManager | CandidClientManager | Yes | Client manager with agent access |
didjsCanisterId | CanisterId | No | Custom didjs canister ID |
The didjs canister ID is auto-selected based on network:
- IC Mainnet:
a4gq6-oaaaa-aaaab-qaa4q-cai - Local:
a4gq6-oaaaa-aaaab-qaa4q-cai(same, but requires local deployment)
Methods
Section titled “Methods”getCandidDefinition(canisterId)
Section titled “getCandidDefinition(canisterId)”Fetch and parse Candid for a canister in one call.
const { idlFactory, init } = await adapter.getCandidDefinition( "ryjl3-tyaaa-aaaaa-aaaba-cai")
// Use the idlFactoryconst service = idlFactory({ IDL })console.log(service._fields) // Method definitionsReturns
Section titled “Returns”interface CandidDefinition { idlFactory: IDL.InterfaceFactory init?: (args: { IDL: typeof IDL }) => IDL.Type<unknown>[]}fetchCandidSource(canisterId)
Section titled “fetchCandidSource(canisterId)”Fetch raw Candid source text from a canister.
const candidSource = await adapter.fetchCandidSource( "ryjl3-tyaaa-aaaaa-aaaba-cai")console.log(candidSource)// service { icrc1_name : () -> (text) query; ... }parseCandidSource(candidSource)
Section titled “parseCandidSource(candidSource)”Parse Candid source text into an IDL factory.
const candidSource = ` service : { greet : (text) -> (text) query; }`
const { idlFactory } = await adapter.parseCandidSource(candidSource)This method:
- Tries local parsing if the parser is loaded
- Falls back to remote compilation via didjs canister
loadParser()
Section titled “loadParser()”Load the local WASM parser for offline compilation.
import { CandidAdapter } from "@ic-reactor/candid"import "@ic-reactor/parser" // Required peer dependency
const adapter = new CandidAdapter({ clientManager })
// Load the parser (only needed once)await adapter.loadParser()
// Now compileLocal worksconst definition = adapter.compileLocal(candidSource)compileLocal(candidSource)
Section titled “compileLocal(candidSource)”Compile Candid using the local WASM parser (synchronous after loading).
// Requires loadParser() firstconst { idlFactory } = adapter.compileLocal(candidSource)Throws if the parser hasn’t been loaded.
compileRemote(candidSource)
Section titled “compileRemote(candidSource)”Compile Candid using the didjs canister.
const { idlFactory } = await adapter.compileRemote(candidSource)This is the fallback method when local parsing isn’t available.
validateCandid(candidSource)
Section titled “validateCandid(candidSource)”Validate Candid syntax without compiling.
await adapter.loadParser()
const isValid = adapter.validateCandid(` service { greet: (text) -> (text) query; }`)console.log(isValid) // trueRequires the parser to be loaded.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
clientManager | CandidClientManager | The client manager instance |
didjsCanisterId | CanisterId | The didjs canister ID in use |
Examples
Section titled “Examples”Basic Usage
Section titled “Basic Usage”import { CandidAdapter } from "@ic-reactor/candid"import { ClientManager } from "@ic-reactor/core"
const clientManager = new ClientManager()await clientManager.initialize()
const adapter = new CandidAdapter({ clientManager })
// Get full definitionconst { idlFactory } = await adapter.getCandidDefinition( "ryjl3-tyaaa-aaaaa-aaaba-cai")
// List methodsconst service = idlFactory({ IDL })for (const [name, func] of service._fields) { console.log(`${name}: ${func.toString()}`)}With Local Parser
Section titled “With Local Parser”import { CandidAdapter } from "@ic-reactor/candid"import "@ic-reactor/parser"
const adapter = new CandidAdapter({ clientManager })
// Load parser once at startupawait adapter.loadParser()
// All subsequent compilations are local (fast!)const candidSource = await adapter.fetchCandidSource(canisterId)const { idlFactory } = adapter.compileLocal(candidSource)Error Handling
Section titled “Error Handling”try { const definition = await adapter.getCandidDefinition(canisterId)} catch (error) { if (error.message.includes("has no query method")) { console.log("Canister doesn't expose Candid metadata") } else if (error.message.includes("compilation failed")) { console.log("Invalid Candid syntax") } else { throw error }}Method Signature Parsing
Section titled “Method Signature Parsing”For dynamic calls, you can parse individual method signatures:
// Parse a method signature wrapped in a serviceconst methodSignature = "(record { owner : principal }) -> (nat) query"const serviceSource = `service : { my_method : ${methodSignature}; }`
const { idlFactory } = await adapter.parseCandidSource(serviceSource)const service = idlFactory({ IDL })
// Extract the method's type informationconst funcField = service._fields.find(([name]) => name === "my_method")const func = funcField[1]
console.log("Arg types:", func.argTypes)console.log("Return types:", func.retTypes)console.log("Is query:", func.annotations.includes("query"))Best Practices
Section titled “Best Practices”See Also
Section titled “See Also”- CandidReactor — High-level dynamic Reactor
- @ic-reactor/candid Overview — Package overview
- @ic-reactor/parser — Local WASM parser reference
- Reactor — Base Reactor class