Install_code() - Easiest way to convert a .wasm module to [Nat8]?

My goal is to have a canister create a new canister and install a pre-built wasm module. Now, the install_code() function of the management canister expects type [Nat8] as an argument for the wasm module. I’ve read some related threads, but wasn’t able to get a solution from it unfortunately. If I’m not mistaken, all I need to do is to somehow convert the wasm module to a [Nat8] array and hard-code the argument for the install_code() function. My problem is that I don’t know how to convert the wasm module to an appropriate format so that I could store it in the (parent-)canister like so:

let wasmBlob : [Nat8] = [];

public shared(msg) func uploadWasm(wasm : [Nat8]) : async () {
    wasmBlob := wasm;

As always, any help would be much appreciated :slight_smile:

Got that in Papyrs in Motoko+NodeJS if it can help?


 private stable var storageWasm : [Nat8] = [];

public shared ({caller}) func storageLoadWasm(blob : [Nat8]) : async ({total : Nat; chunks : Nat}) {
    if (not Utils.isAdmin(caller)) {
      throw Error.reject("Unauthorized access. Caller is not an admin. " # Principal.toText(caller));

    // Issue:
    // let buffer: Buffer.Buffer<Nat8> = Buffer.fromArray<Nat8>(storageWasm);
    // let chunks: Buffer.Buffer<Nat8> = Buffer.fromArray<Nat8>(blob);
    // buffer.append(chunks);
    // storageWasm := buffer.toArray();

    storageWasm := Array.append<Nat8>(storageWasm, blob);

    // return total wasm sizes
    return {
      total = storageWasm.size();
      chunks = blob.size();

JS script load the wasm to array as follow:

export const loadWasm = async (type) => {
  const buffer = await readFile(`${process.cwd()}/.dfx/local/canisters/${type}/${type}.wasm`);
  return [ Uint8Array(buffer)];

and the the scripts chunks and upload it:

const installWasm = async ({actor, type, wasmModule}) => {
  console.log(`Installing ${type} wasm code in manager.`);

  const chunkSize = 700000;

  const upload = async (chunks) => {
    const result = await actor.storageLoadWasm(chunks); // <---- here call of above Motoko endpoint
    console.log('Chunks:', result);

  for (let start = 0; start < wasmModule.length; start += chunkSize) {
    const chunks = wasmModule.slice(start, start + chunkSize);
    await upload(chunks);

  console.log(`Installation ${type} done.`);

Source in this repo:

1 Like

Depending on the size of your Wasm module, the Motoko compiler won’t be able to process it if it’s an array. See:

So you must convert your wasm module to hexadecimal first (there are a many options online and some Unix tools to do that offline) and convert the result to be compatible with Motoko’s Text, like:

let wasmModule: Blob = "\de\ad\be\ef";

Then it’s simple to install the module:

let id = await IC.create_canister({
     settings = ?{
        controllers = ?[Principal.fromActor(this)];
        compute_allocation = null;
        memory_allocation = null;
        freezing_threshold = null;
  await IC.install_code({
      mode = #install;
      canister_id = id.canister_id;
      wasm_module = wasmModule;
      arg = to_candid({
          //your canister's arguments, ex: foo = 1234;

I will try this out victor. Thank you and regards

1 Like

Sorry for my late response, took me some time. I tried Victor’s approach and it works perfectly. Thank you both for your answers!


Karim sir,
How did you converted wasm to blob, which tool did you used?

Hi all, I have a question here:
can we dynamically generate candid method, read wasm code, and install wasm code on chain?