AgentError: Invalid certificate: Signature verification failed with NodeJS

I’m trying to call my APIs with NodeJS.

Here’s my code:

import { idlFactory } from '../../declarations/user_index/user_index.did.js';
import { Actor, HttpAgent } from '@dfinity/agent';
import canisterIds from '../../../../.dfx/local/canister_ids.json' assert { type: 'json' };
const canisterId = canisterIds.user_index.local;

const host = 'http://127.0.0.1:4943';

const agent = new HttpAgent({ fetch, host });
await agent.fetchRootKey();
const userIndexActor = Actor.createActor(idlFactory, {
	canisterId,
	agent: new HttpAgent({ host, fetch })
});
const anonPrincipalId = await userIndexActor.get_my_id();

console.log(anonPrincipalId.toText());

On running this node test.js, I get the following error:"

/xxx/node_modules/@dfinity/agent/lib/cjs/certificate.js:142
            throw new CertificateVerificationError('Signature verification failed');
                  ^

AgentError: Invalid certificate: Signature verification failed
    at Certificate.verify (/xxx/node_modules/@dfinity/agent/lib/cjs/certificate.js:142:19)
    at async Certificate.create (/xxx/node_modules/@dfinity/agent/lib/cjs/certificate.js:122:9)
    at async pollForResponse (/xxx/node_modules/@dfinity/agent/lib/cjs/polling/index.js:51:18)
    at async caller (/xxx/node_modules/@dfinity/agent/lib/cjs/actor.js:190:35)

I have gone through all the posts for calling canisters with NodeJS and nothing is yet working for me.

I’m using NodeJs 18.12.1 and dfx sdk version 0.12.1

I believe you need to use the agent you initialised instead of creating a new agent.

Have you tried fetching the root cert for userIndexActor?

My bad,

I updated the code to following:

import { idlFactory } from '../../declarations/user_index/user_index.did.js';
import { Actor, HttpAgent } from '@dfinity/agent';
import canisterIds from '../../../../.dfx/local/canister_ids.json' assert { type: 'json' };
const canisterId = canisterIds.user_index.local;

const host = 'http://127.0.0.1:4943';
const identity = Ed25519KeyIdentity.generate();
const agent = new HttpAgent({ host, identity });
await agent.fetchRootKey();

const userIndexActor = Actor.createActor(idlFactory, {
	canisterId,
	agent
});
const anonPrincipalId = await userIndexActor.get_my_id();

console.log(anonPrincipalId.toText());

I’m getting another error now:

(node:37087) ExperimentalWarning: The Node.js specifier resolution flag is experimental. It could change or be removed at any time.
(Use `node --trace-warnings ...` to show where the warning was created)
(node:37087) ExperimentalWarning: Importing JSON modules is an experimental feature. This feature could change at any time
/client/node_modules/@dfinity/agent/lib/cjs/agent/http/index.js:141
                throw new Error('Must specify a host to connect to.');
                      ^

Error: Must specify a host to connect to.
    at new HttpAgent (/client/node_modules/@dfinity/agent/lib/cjs/agent/http/index.js:141:23)
    at createActor (file:///client/declarations/user_index/index.js:11:33)
    at file:///client/declarations/user_index/index.js:36:27
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async loadESM (node:internal/process/esm_loader:91:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)

Node.js v18.12.1

This error could be an agent instance somewhere that’s trying to load before you pass it the host, you can check the imports where you have agents and try to debug it there.

Let me create a minimal reproduction for this.