moxzi
Docs / Reference / Compiler canister API

Compiler canister APIalpha

The Candid methods of the on-chain compiler canister, grouped by task.

moxzi build --remote calls these methods for you. Use this page if you're writing your own client, or investigating a build. The canister's candid:service metadata has the full interface:

dfx canister --network ic --identity anonymous metadata xcn6l-iqaaa-aaaai-raq6q-cai candid:service

The shape of a build#

A build is a job. You put sources into the canister's virtual filesystem, start a job over an entry point, drive it one step at a time until it reports #done, then pull the artifact out in chunks. Nothing about it is a single long-running call, because nothing on the Internet Computer can be: each step is a separate message under the replica's 40-billion instruction cap.

step returns a Step, which is the whole state machine:

VariantMeaning
#moreNot finished. Call step again.
#done : blobFinished. The blob is the unlinked artifact.
#err : vec MessageFailed, with structured diagnostics — code, severity, source region, notes and suggested edits.
#needClass : textThe build needs an actor-class module compiled first, named by path.

Starting a job#

MethodPurpose
start : (Options) -> (JobId)Start a job you will drive yourself with step.
startSelfDriven : (Options) -> (JobId)Start a job the canister advances on its own timer.
startEscrowed : (Options) -> (PaidStart)Quote at the CMC rate, pull the maximum a compile could cost, and record a settlement.
startPaid : (Options) -> (PaidStart)Charge the caller, then start. The pull happens first: if it fails there is no job.
cancel : (JobId) -> ()Stop a running job.

Options carries the entry path plus the same knobs the CLI exposes: debug, eop, stackBudget, forceGc, stableRegions, maxStablePages, stabilizationInstructionLimit, measureRtsStack, trapOnCallError, defaultPersistentActors, enhancedMigration and stableBaseline (the migration-chain pair — the directory is a VFS path, the baseline is the .most text itself), publicMetadata and omitMetadata, and the internal codegenInstrBudget, parseWindow and pauseBeforeCodegen.

startEscrowed is the interesting one. It pulls a maximum up front, which is what makes the compile safe to run without a per-message payment check, and refunds the difference at settleStep. See what a build costs.

Driving and watching#

MethodPurpose
step : (JobId) -> (Step)Advance the job by one message.
status : (JobId) -> (opt Status) (query)Phase name, message count, yields, instructions used.
jobStats : () -> (…)Counts across all jobs.
jobDiags : (JobId) -> (opt vec text) (query)Diagnostics recorded for a job.
sdStatus : () -> (bool, nat, text) (query)State of the self-driven job runner.
sdPoke : (JobId) -> (bool)Nudge the self-driven runner.

Poll status no more than every few seconds. sdPoke restarts a stuck self-driven job; don't use it for routine driving.

Getting the artifact out#

MethodPurpose
getArtifact : (JobId) -> (opt blob) (query)The whole artifact, if it fits in one reply.
getArtifactChunk : (JobId, offset) -> (opt blob) (query)The artifact in pieces.
jobWasmSize : (JobId) -> (nat) (query)How many bytes to expect.
jobWasmChunk : (JobId, offset) -> (blob) (query)The wasm in pieces.
getCandid : (JobId) -> (opt text) (query)The generated Candid interface.
releaseJob : (JobId) -> (bool)Release the job's stored artifact.

These return the unlinked module. See Linking and installing.

Linking and build records#

MethodPurpose
linkArtifact : (JobId, compact : bool) -> (…)Link the job's module in the canister and record the linked hash
getLinkedChunk : (JobId, offset) -> (opt blob) (query)The linked module in pieces
attestLinked : (sha256 : text) -> (opt …) (query)The build record for a linked module with this hash, or null if the canister didn't link it
buildRecord : (JobId) -> (opt BuildRecord) (query)Source digest, options digest, compiler version and artifact hash
buildSources : (JobId) -> (opt vec (text, text)) (query)Each source path and its SHA-256, for recent builds
recentBuilds : (nat) -> (vec (JobId, BuildRecord)) (query)The most recent build records

Anyone can call these. moxzi verify uses them.

The virtual filesystem#

MethodPurpose
write : (path, blob) -> ()Write a file.
appendChunk : (path, blob) -> ()Append to a file, for sources larger than one message.
read : (path) -> (opt blob) (query)Read a file back.
remove : (path) -> ()Delete a file.
removeExcept : (vec path) -> (nat)Delete every file not in the list; returns how many were deleted.
list : () -> (vec text) (query)Every path in your tree.
vfsStats : () -> (…) (query)Per-caller and total usage against the limits.

Each caller has its own files. The canister's controllers can read them.

Content-addressed blobs and tags#

MethodPurpose
putBlobs : (vec blob) -> (vec text)Store blobs, returning their hashes.
putBlobFromFile : (path) -> (opt text)Hash a file already in the VFS into the blob store.
missingBlobs : (vec text) -> (vec text) (query)Which hashes are not stored. Upload only these.
blobHash : (blob) -> (text) (query)Hash a blob without storing it.
blobStoreStats : () -> (…)Store occupancy.
putTag / putTagFromRegister a (package, version) manifest over stored blobs.
haveTag : (text) -> (bool) (query)Is this tag registered?
tagFiles : (text) -> (opt …) (query)The files a tag names.
useTags : (vec text) -> (TagResult)Materialise registered tags into the caller's VFS.

A client hashes files locally, asks missingBlobs which the canister lacks, and uploads only those. useTags accepts only tags that passed verifyTagAgainstMops. See Sources and packages.

Provenance and verification#

MethodPurpose
verifyTag : (text) -> (opt …) (query)Re-hash every blob a tag references and confirm it still matches its key.
verifyTagAgainstMops : (text) -> (MopsCheck)Compare a registered tag against what mops published, by name and content.
tagProvenanceOf : (text) -> (opt …) (query)Who registered a tag, when, and from where.
tagMopsVerifiedAt : (text) -> (opt nat64) (query)When the tag last passed mops verification.

In MopsCheck, mismatched lists files whose content differs from what mops published. Each list is capped at 20 entries.

Payment and settlement#

MethodPurpose
quoteEscrowFor : (sourceBytes) -> (…)What startEscrowed would pull right now, for a build of this size.
quoteEscrow : () -> (…)The older flat quote, kept for existing clients.
settleStep : (JobId) -> (SettleStep)Advance settlement by exactly one step.
getSettlement : (JobId) -> (…)Where a settlement got to.
abandonSettlement : (JobId) -> (SettleStep)Give up on a stuck settlement.
jobCharge : (JobId) -> (opt nat) (query)What a job was charged.
refundJob : (JobId) -> (…)Refund a job's charge, once. Operator-only.
getPrice, getBillingRates, revenue, icpXdrRate (queries)Current pricing and takings.

quoteEscrowFor is an update because it asks the Cycles Minting Canister for the current rate. Use its result rather than computing the escrow yourself.

settleStep can be retried safely: a failed step changes nothing, and each transfer happens once. Call it until it returns #done.

Operator methods#

These require the caller to be an operator:

setPrice, setBillingRates, setChargeMultiplier, setEscrowCycles, setEscrowFloor, setEscrowPerByte, setLedger, setCmc, setMopsRegistry, setDonationSinks, setCacheVersion, clearBuildCache, getOperators, isOperatorQuery, syncOperators, getDonationSinks, buildCacheStats, installFresh.

syncOperators copies the canister's controllers into the operator list. Anyone can call it. The build cache is off until an operator calls setCacheVersion.

Diagnostic and internal methods#

For development and troubleshooting; not supported for clients: runCachedCodegen, startCachedCodegen, cgResultChunk, cgRunStatus, cgYields, codegenSnapshotReady, armCodegenTrap.

On this pageThe shape of a buildStarting a jobDriving and watchingGetting the artifact outLinking and build recordsThe virtual filesystemContent-addressed blobs and tagsProvenance and verificationPayment and settlementOperator methodsDiagnostic and internal methods