# Reading wasm module blob in Nodejs

**URL:** <https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638>\
**Category:** JavaScript\
**Created:** [February 2, 2022, 12:19pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638 "2022-02-02T12:19:47Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 2, 2022, 12:19pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/1 "2022-02-02T12:19:47Z")

</div>

Support

I’m trying to call install\_code function from Nodejs. For that i’m reading wasm file as below,

const wasm = fs.readFileSync("\<file\_name\>.wasm")  
Then invoke the method by passing […new Uint8Array(wasm)].

But my request rejects with  
Reject code: 4  
Reject text: Canister trapped explicitly: IDL error: word read out of buffer

Any help!

---

<div class="post-metadata">

**Author:** ![senior.joinu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/senior.joinu/32/9240_2.png) [@senior.joinu](https://forum.dfinity.org/u/senior.joinu)\
**Post date:** [February 2, 2022, 1:27pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/2 "2022-02-02T13:27:35Z")

</div>

Could you please provide more details on how you actually invoke the method. The more code you can provide the better.

---

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 2, 2022, 2:08pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/3 "2022-02-02T14:08:26Z")

</div>

Thank you for the quick response!

Nodejs code for motoko canister call

```auto
const idlFactory = ({ IDL }) => {
    const Key = IDL.Text;
    const Value = IDL.Record({ 'age' : IDL.Int, 'name' : IDL.Text });
    return IDL.Service({
      'upgradesub' : IDL.Func([IDL.Vec(IDL.Nat8), IDL.Vec(IDL.Nat8)], [], []),
    });
  };

const testaudit = createActor(canisterId, {
    agentOptions: { host: "http://localhost:8000",}
});

let updateSubCanisters = async () => {
    const wasm = fs.readFileSync("./../../.dfx/local/canisters/testaudit/testaudit.wasm")
    const res = await testaudit.upgradesub([...new Uint8Array(wasm)], [...new 
    Uint8Array(Buffer.from("Xep"))]).catch(e => { return "Error" + e });
    return res;
}

```

Motoko canister function

```auto
 public func upgradesub(wasm: Blob, args: Blob) : async () {
    Debug.print("upgrade_sub: ");
      for ((key, bucket) in buckets.entries()) {
        let principal = Principal.fromActor(bucket);
        let status = await IC.canister_status({canister_id=principal});
        Debug.print("cycles: " # Nat.toText(status.cycles));
        await IC.stop_canister({canister_id=principal});
        await IC.install_code({canister_id=principal; mode=#upgrade; wasm_module=wasm; arg=args});
        await IC.start_canister({canister_id=principal});
      };
  };

```

This is the response I’m getting

```auto
The given bytes are a valid wasm module
ErrorError: Call was rejected:
  Request ID: 2ae15b8f3ec0d64659e4d44968f329341985866e6448e6c8a1660b2b6f1580da
  Reject code: 4
  Reject text: Canister <canister-id> trapped explicitly: IDL error: word read out of buffer

```

I read my buffer needs to encode in Candid data format, But I don’t know how to do it.

---

<div class="post-metadata">

**Author:** ![senior.joinu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/senior.joinu/32/9240_2.png) [@senior.joinu](https://forum.dfinity.org/u/senior.joinu)\
**Post date:** [February 2, 2022, 2:24pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/4 "2022-02-02T14:24:33Z")

</div>

Yes, there is an error.

```javascript
const res = await testaudit.upgradesub([...new Uint8Array(wasm)], [...new 
    Uint8Array(Buffer.from("Xep"))]).catch(e => { return "Error" + e });

```

Args should be candid-encoded, not plain text.

I don’t know your interfaces, but basically you have to use `IDL.encode()` function. For example, if your `init` canister function takes a `Text` as an argument, on js side you should encode it like:

```auto
const args = Array.from(IDL.encode([IDL.Text], ["Xep"]));

```

and then use it like this:

```auto
const res = await testaudit.upgradesub([...new Uint8Array(wasm)], args);

```

I might make a mistake, but it seems like a right direction to look for an error.

---

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 2, 2022, 3:00pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/5 "2022-02-02T15:00:27Z")

</div>

It changed the previous error. I updated my Nodejs function as below,

```auto
let updateSubCanisters = async () => {
    const wasm = fs.readFileSync("./../../.dfx/local/canisters/testaudit/testaudit.wasm")
    const args = Array.from(IDL.encode([IDL.Text], ["Xep"]));
    console.log(args)
    const res = await testaudit.upgradesub([...new Uint8Array(wasm)], args).catch(e => { return "Error" + e });
    return res;
}

```

args print output

```auto
[
  68, 73, 68, 76, 0,
   3, 113, 1, 88
]

```

And now I’m receiving following error

```auto
[ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined

```

I’m trying to update my org.mo dynamic canisters initiated by main.mo canister via main canister.

main.mo

```auto
actor {
    type Org = orgs.Org;
    type Key = Text;
    type Value = person.Person;
    let IC : ICType.Self = actor "aaaaa-aa";

    stable var entries : [(Text, Org)] = [];

    let buckets = Map.fromIter<Text,Org>(entries.vals(), 10, Text.equal, Text.hash);

    public func put(o: Text, k : Key, v : Value) : async () {
        let bucket = switch (buckets.get(o)) {
        case null {
            // provision next send, 
            let b = await orgs.Org(o); // dynamically install a new Bucket
            buckets.put(o, b);
            b;
        };
        case (?bucket) bucket;
        };
        await bucket.put(k, v);
  };

  public func upgradesub(wasm: Blob, args: Blob) : async () {
    Debug.print("upgrade_sub: ");
      for ((key, bucket) in buckets.entries()) {
        let principal = Principal.fromActor(bucket);
        let status = await IC.canister_status({canister_id=principal});
        Debug.print("cycles: " # Nat.toText(status.cycles));
        await IC.stop_canister({canister_id=principal});
        await IC.install_code({canister_id=principal; mode=#upgrade; wasm_module=wasm; arg=args});
        await IC.start_canister({canister_id=principal});
      };
  };

```

Org.mo canister

```auto
actor class Org(n : Text) {
};

```

Any idea what I’m missing here. Appreciate your help.

---

<div class="post-metadata">

**Author:** ![senior.joinu](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/senior.joinu/32/9240_2.png) [@senior.joinu](https://forum.dfinity.org/u/senior.joinu)\
**Post date:** [February 2, 2022, 3:20pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/6 "2022-02-02T15:20:48Z")

</div>

Does

```auto
console.log(wasm);

```

print something?

Looks like one of your variables is undefined.

---

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 2, 2022, 3:30pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/7 "2022-02-02T15:30:42Z")

</div>

Updated as below

```auto
let updateSubCanisters = async () => {
    const wasm = fs.readFileSync("./../../.dfx/local/canisters/testaudit/testaudit.wasm")
    var valid = WebAssembly.validate(new Uint8Array(wasm));
    console.log("The given bytes are " + (valid ? "" : "not ") + "a valid wasm module");
    console.log(wasm);
    const args = Array.from(IDL.encode([IDL.Text], ["Xep"]));
    console.log(args)
    const res = await testaudit.upgradesub([...new Uint8Array(wasm)], args).catch(e => { return "Error" + e });
    return res;
}

```

Output

```auto
The given bytes are a valid wasm module
<Buffer 00 61 73 6d 01 00 00 00 01 ee 81 80 80 00 26 60 02 7f 7f 00 60 01 7e 00 60 08 7f 7f 7f 7f 7f 7f 7f 7f 00 60 00 01 7f 60 00 01 7e 60 03 7f 7f 7f 00 60 ... 435195 more bytes>
[
   68, 73, 68, 76, 0,
    1, 113, 3, 88, 101,
  112
]

```

Thanks!

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [February 2, 2022, 5:52pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/8 "2022-02-02T17:52:23Z")

</div>

It is still under development, that’s why my code is still in a branch, but i’ve got a working example: [deckdeckgo/ic.installcode.mjs at build/install-code · deckgo/deckdeckgo · GitHub](https://github.com/deckgo/deckdeckgo/blob/build/install-code/canisters/scripts/ic.installcode.mjs)

For me the tricks was

1. be sure that the local candid description is up-to-date
2. encode the canister parameters as candid parameters ([thread](https://forum.dfinity.org/t/encode-principal-to-candid-arguments/10465))

Not sure it is your error but maybe by comparing you will notice something. Hope it helps.

---

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 3, 2022, 2:20am UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/9 "2022-02-03T02:20:36Z")

</div>

It has what I want to do. I’ll follow the repo. Thanks for the help!

---

<div class="post-metadata">

**Author:** ![palinda](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/palinda/32/4516_2.png) [@palinda](https://forum.dfinity.org/u/palinda)\
**Post date:** [February 7, 2022, 8:27am UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/10 "2022-02-07T08:27:54Z")

</div>

I went through the code, I was able to do my requirement. But I like to do an improvement, In the below code owner is parsed as a parameter from the outside. Can I use some Text data inside the canister as an argument?.  
file: canister.utils.mo

```auto
public func installCode(canisterId: Principal, owner: Blob, wasmModule: Blob): async() {
            await ic.install_code({
                arg = owner;
                wasm_module = wasmModule;
                mode = #upgrade;
                canister_id = canisterId;
            });
        };

```

Expected:

```auto
private stable var owner : Text= "me";
public func installCode(canisterId: Principal, wasmModule: Blob): async() {
            await ic.install_code({
                arg = text_to_candid_encode_blob(owner); <---- requirement
                wasm_module = wasmModule;
                mode = #upgrade;
                canister_id = canisterId;
            });
        };

```

Thanks!

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [February 7, 2022, 3:11pm UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/11 "2022-02-07T15:11:46Z")

</div>

It’s an on-going PR. The parameter `owner: Blob` should actually be renamed to something like “any args”.

```auto
public func installCode(canisterId: Principal, anyArgs: Blob, wasmModule: Blob): async() {

```

These args are encoded in the [JS code](https://github.com/deckgo/deckdeckgo/blob/5ec5c9076344de36fdbcd583af45016aae1665c3/canisters/scripts/ic.installcode.mjs#L62).

There I guess yes in the JS code you can extend the code or modify the code to pass the parameters you want, those needed by your canister.

---

<div class="post-metadata">

**Author:** ![shashika](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/shashika/32/4622_2.png) [@shashika](https://forum.dfinity.org/u/shashika)\
**Post date:** [March 31, 2022, 11:27am UTC](https://forum.dfinity.org/t/reading-wasm-module-blob-in-nodejs/10638/12 "2022-03-31T11:27:42Z")

</div>

Hi all, I faced the same issue as above when passing the parameters for install\_code method to upgrade canisters using NodeJs.

```auto
let updateSubCanisters = async () => {
    const wasm = fs.readFileSync("./../../.dfx/local/canisters/testaudit/testaudit.wasm")
   // const args = Array.from(IDL.encode([IDL.Text], ["Xep"])); <---- instead of Array use Uint8Array as below
    const args = [... new Uint8Array(IDL.encode([IDL.Text], ["Xep"]))];
    console.log(args)
    const res = await testaudit.upgradesub(
  [...new Uint8Array(wasm)], 
  args
).catch(e => { return "Error" + e });
    return res;
}

```

The problem here is that a simple array is treated as Candid [Nat8] and Uint8Array is treated as a Candid Blob data type respectively.
