I want to solve `Mint error: Error: Invalid certificate: Signature verification failed` and run the mint function from the front end

Hello!

I am currently having trouble calling the DIP20 token canister mint function from the front end.
I have confirmed that I can call it directly on the terminal using dfx, but I would like to do the same thing on the front end.

What I want to do
I want to use the mint function to grant a token to a user who has logged in with Internet Identity.

Error
Mint error: Error: Invalid certificate: Signature verification failed.

[ Put Error ]

    const handleFaucet = async () => {
      try {
        const result = await DIP20Actor.mint(Principal.fromText(currentPrincipalId), 10000);
        console.log(result);
      } catch (error) {
        console.log(`Mint error: ${error}`); // Put Error
      }
    }

[ Implementation Create Actor ]

import { Actor, HttpAgent } from "@dfinity/agent";
import { AuthClient } from "@dfinity/auth-client";
import { Principal } from '@dfinity/principal';
import { canisterId as IICanisterID } from "../../declarations/internet_identity";
import { canisterId as DIP20canisterId } from '../../declarations/DIP20';
import { idlFactory as idlFactory } from '../../declarations/DIP20/DIP20.did.js';

const App = () => {
    // Start Login process.
    // First we have to create and AuthClient.
    const authClient = await AuthClient.create();

    setAuthClient(authClient);

    // Login with Internet Identity.
    await new Promise((resolve, reject) => {
      authClient.login({
        identityProvider: iiUrl,
        onSuccess: resolve,
        onError: reject,
      });
    });

    // Get the identity from the auth client:
    const identity = authClient.getIdentity();
    // Using the identity obtained from the auth client, we can create an agent to interact with the IC.
    const agent = new HttpAgent({ identity });
    const handleFaucet = async () => {
    const DIP20Actor = Actor.createActor(idlFactory, {
      agent,
      canisterId: DIP20canisterId,
    });

What I would like to know.

  • What part/interaction on IC is giving this error content?
  • How to solve it (do I need to change anything when I run agent, createActor?)

Thank you in advance.

The agent has the public key of the IC baked in for security; everything is ultimately authenticated against that key. If you are running the replica locally, it won’t have that key, so you must call await agent.fetchRootKey() (but only if running against the local replica).

3 Likes

Thanks for your response!
I have successfully called the generic method by calling fetchRootKey().

There is one more thing I wanted to know.
When calling mint() on the DIP20 token standard, it returns an Unauthorized error saying that the owner of the DIP20 canister and the person who actually calls mint do not match, caught in the following part.

public shared(msg) func mint(to: Principal, value: Nat): async TxReceipt {
        if(msg.caller ! = owner_) {
            return #Err(#Unauthorized);
        };

Is there any way to call such a restricted method from the front end?
Or do I still have to modify mint() (remove restrictions)?

Nothing stops you from adding a privileged users system to the code, and then leveraging Internet Identity to provide a frontend principal.

Thank you.

I have done a lot of research since your response, but have not figured out how to implement it.

I am wondering if I need to specify something when executing const agent = new HttpAgent({identity}), but I have not been able to find any documentation or references…

Thank you in advance for your help.

Are you using @dfinity/auth-client?

Yes, I use Internet-Identity for user authentication. I also import @dfinity/agent and @dfinity/auth-clien to handle canisters on the frontend.

This is my code

If you’re logging in correctly to an II-based principal (check that (await agent.getPrincipal()).toText() !== "2vxsx-fae"), then the only thing left to do is add code to the canister for authorizing this principal. Likely an additional function to allow the owner to designate new minting-capable accounts.

1 Like