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

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

Canister:

 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: https://forum.dfinity.org/t/array-to-buffer-in-motoko/15880/15
    // 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 [...new 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: https://github.com/papyrs/ic

2 Likes