Publishing to a registryalpha
How does a wasm get the "built on-chain" verdict, and who decides it?
A build that ran on the compiler canister can be published to an ICRC-118 registry with a record of how it was made, and the registry can check that record against the compiler itself. The reference registry is astroflora: l55bi-3aaaa-aaaai-atk4a-cai, with a UI at https://registry.astroflora.xyz.
Two things before the first publish#
Publication is open, and gated twice.
- A namespace. Namespaces are reverse-DNS (
com.example.myapp). The registry lets a principal create a type only if the ICRC-86 domain registry says it controls a claimed domain that is a prefix of the namespace. Claimexample.comonce (5 XDR in ICP), prove it with a TXT record at_icrc86.example.com, and every namespace under it is yours. - Storage. Every chunk you upload is charged to your byte cap, which starts at zero. Storage is bought: 30 XDR in ICP per 70 MB, pro rata, good for three years.
Both are done on the registry's Publishing access page. A refusal from the registry names the missing step.
The commands#
moxzi build src/Main.mo --remote https://icp-api.io --canister xcn6l-iqaaa-aaaai-raq6q-cai
moxzi publish out/Main.wasm --registry l55bi-3aaaa-aaaai-atk4a-cai \
--namespace com.example.myapp --version 1.0.0 --canister xcn6l-iqaaa-aaaai-raq6q-cai
--canister points publish at the build that made the file, so the entry carries the source digest, the options digest, the compiler version and the linked hash, read from the compiler's own records rather than computed on your machine. --previous chains a release to the one it upgrades; moxzi deprecate marks one superseded without removing it.
The verdict is pulled, not pushed#
After the upload, publish asks the registry to pull the compiler's attestation. The registry calls the compiler canister with the linked sha256 of the bytes it now holds (attestLinked), and files what it hears as the compiler's own ICRC-126 attestation. Then it prints one of three words:
verified— the compiler linked exactly these bytes. Built on-chain.unverified— the compiler never linked them. A locally built wasm publishes fine and lands here; so does an on-chain build whose file was modified after linking.DIVERGENT— someone filed a divergence report that has not been resolved. An open report outranks every attestation, the compiler's included.
Nothing the CLI prints is evidence. The compiler's records are public canister state and its answer is a query, so anyone can repeat the question: change one byte of a verified wasm and the answer is a definite null.
What cannot be attested#
A --compact-rts link is the off-chain runtime's build; publish refuses it unless you pass --allow-offchain. --ephemeral and memory caps rewrite the module after the compiler signed off, so those artifacts publish as unverified.