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