Grab calling principal in local environment

Hi,

I’m having trouble learning how to use the Internet Identity in a locally deployed canister; specifically using the shared({caller}) function.

Suppose I have a function:

public shared({caller}) func getCallingPrincipal() : async Principal {
    return caller;
};

And I want to call it from javascript. Currently, this only works when the canister is deployed to the IC.

What I am doing:

const identity = authClient.getIdentity()

if (identity) {
  this.aCanister = createActor(canisterId, {
    agentOptions: {
      identity,
      host: this.localhost
    }
  })
  this. getCallingPrincipal();
}

Can someone give me a nudge in the right direction please?

Bump. Please help I’m running out of hair to pull out.

What error do you get or where are you stuck?

Without an error message or other information it’s hard to say.

You may need do call fetchRootKey but that’s a complete guess.

1 Like

Thanks team. So read through a few repo’s and have it working by cloning II canister locally and using that.

  1. Is it actually possible to do this with the deployed II canister or must I use a local version of the II canister when developing locally?
  2. Looks like it is fetching the root key in the createActor method generated by Motoko. I wonder if I need to do it manually? It appears to be successfully returning a giant blob as is
  3. The specific error is:
Failed to authenticate request xxxxxxxsomewhatlonghashxxxxx due to: Invalid delegation: Invalid canister signature: IcCanisterSignature signature could not be verified: public key xxxxxxxxxxreallylonghashxxxxxxx, error: certificate verification failed: failed to verify threshold signature: certificate_tree_hash=CryptoHash... 

Thanks for the help!

Local deployment requires a local instance of II.

Responses from the IC are signed by the IC’s root key. By default, agent-js (and other agents) check that the keys match, otherwise you could be holding a forged response. Since a local instance does not contain the real IC’s private key, it cannot sign responses with THE root key and it uses a different one. To tell agent-js to fetch the current root key and compare responses against that one, you have to call fetchRootKey. DO NOT DO THIS IN PROD, otherwise you may start accepting forged responses.

The error you showed talks about those certificates and signatures not matching. This (most likely) is exactly the case where the root keys do not match up.

Thank you so much @Severin!

That explains the generated code checking if production to call fetchRootKey.

For those on the hunt for answers, in summary:

if I want to grab the method caller’s principal using shared({caller}) locally, you must deploy and authenticate with a local version of the Internet Identity canister.

@kpeacock made some awesome tutorials here: Integrating with Internet Identity which helped tremendously.

2 Likes