File upload with node.js

Hi,
I’m looking for an example how I can upload e.g a JSON file to an asset canister from a nodeJs backend.

I grateful for any hint’s
Cheers Roland

In got a script where I read a local wasm code - a file - and send it to a canister function, would that help?

NodeJS:

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

Send to Motoko’s function / blob parameter wasmModule

public shared ({caller}) func installCode(canisterId : Principal, owner : Blob, wasmModule : Blob) : async () {

Thank you very much, that gives me an idea how this could work. In my example I try to upload a json file to an asset canister which can be directly downloaded as a static file.

1 Like

Hey @rbole,

you might want to check out GitHub - slide-computer/assets-js: Manage assets on an Internet Computer assets canister

2 Likes

Here ya go Using Node.js | Internet Computer Home

2 Likes

Thank you very much for the help, I try to build my solution around this infos. The asset-js lib looks very promising.

One question to the authorization. How can I authorize my local identity? I get the following error message when I try to run my script:

Error: Call was rejected:
Request ID: 28779599c03b952398e5aa614d5e7e1736e25bcb0c841d63b75ab5ba1ca1f3c3
Reject code: 4
Reject text: Caller is not authorized

In short this is my script

const initIdentity = () => {
const buffer = readFileSync(‘/Users/rbole/.config/dfx/identity/default/identity.pem’);
const key = buffer.toString(‘utf-8’);
const privateKey = crypto.createHash(‘sha256’).update(key).digest(‘base64’);

return Secp256k1KeyIdentity.fromSecretKey(Buffer.from(privateKey, ‘base64’));
};

const canisterId = ‘ryjl3-tyaaa-aaaaa-aaaba-cai’;
const identity = initIdentity();

const myAgent = new HttpAgent({identity, fetch, host: ‘http://127.0.0.1:8000’});

console.log(identity)
myAgent.fetchRootKey().catch(err=>{
console.warn(“Unable to fetch root key. Check to ensure that your local replica is running”);
console.error(err);
});

const agent = myAgent // Agent with an authorized identity
const assetManager = new AssetManager({canisterId, agent, concurrency: 32, maxSingleFileSize: 450000,maxChunkSize: 1900000
});

const file = readFileSync(‘./test.json’);
const key = await assetManager.insert(file, {fileName: ‘test.json’});
console.log(key)

I had in mind early year discussion around replicating the identity in NodeJS that it was not yet possible but after checking the thread I started, I landed on following solution which I did not tested but actually seems now to work according feedback :point_right: Using @dfinity/agent in node.js - #55 by ZenVoich

Does it and would it work for you?

Thanks @peterparker the identity is know working. I can also store a new asset json file in the asset canister. I found also the method list to list all assets of the container. The only thing which is not working is the delete method.

Is working:

const file = readFileSync(‘./vvc.json’);
const key = await assetManager.insert(file, {fileName: ‘vvc.json’});
console.log(key)

Is also working:

let r2 = await assetManager.list();
console.log(r2)

But if I try:

let file2del = ‘/vvc.json’
let r = await assetManager.delete(file2del);

I receive the following error:

Error: Call was rejected:
Request ID: 8ee4e2eaf0b3ce3982bc68c7dab3c7b6faae935f52e1608362b62ed75bf5a115
Reject code: 3
Reject text: Canister rrkah-fqaaa-aaaaa-aaaaq-cai has no update method ‘delete_content’

I have never used assetManager and library @slide-computer/assets.

Maybe @kpeacock or @sea-snake - who seems to be the author of the package - can answer your question?

ok, thank you for your time.

I noticed also that in the frontend.did file there is a delete_asset function but no delete_content function ??

I can confirm that if I change the function call from delete_content to delete_asset the delete function is working. I have to change this in the index.modern.js file of the package @slide-computer/assets.

Maybe this lib is using an older dfx version or sometimes the naming in the asset canister, see at assetstorage.did, has changed.

Can someone confirm this bug? or I’m missing something.

I have pushed a pull request to the maintainer of the project. In the meantime you can use a fixed version on Github. GitHub - samlinux/assets-js: Manage assets on an Internet Computer assets canister

1 Like

The library was written based on an older asset canister version indeed. There’s a PR based on this library that fixes this and has additional features here https://github.com/dfinity/agent-js/pull/603

3 Likes

oh great, I didn’t realize that was ready yet!