Deriving the wallet canister id from an authenticated user

Hi,

I have an authenticated user in my dapp that owns some ICP.
Via the AuthClient I retrieve the authenticated identity and derive the principal (e.g.):
authClient.getIdentity().getPrincipal()

When I use this principal to query the ledger balance it returns 0, because the ICP is owned by the wallet canister. But there seems to be no function on how I can retrieve the wallet canister principal.

The solution can’t be that the user has to manually tell me the canister id, right?

Interestingly, the nns dapp does not really do anything different than me. But I still get different outputs.

My code:

export const authWithInternetIdentity = async (): Promise<boolean> => {
  const authClient = await getAuthClient();
  return new Promise(async (resolve, reject) => {
    await authClient.login({
      onError: async (error) => {
        reject('Internet Identity login unsuccessful: ' + error);
      },
      onSuccess: async () => {
        console.log(process.env.NEXT_PUBLIC_INTERNET_IDENTITY); //'https://identity.ic0.app'
        console.log(authClient.getIdentity().getPrincipal().toText());
        resolve(true);
      },
      identityProvider: process.env.NEXT_PUBLIC_INTERNET_IDENTITY,
    });
  });
};

NNS Dapp (nns-dapp/auth.store.ts at main · dfinity/nns-dapp · GitHub):

 signIn: () =>
      new Promise<void>((resolve, reject) => {
        AuthClient.create().then((authClient: AuthClient) => {
          authClient.login({
            identityProvider: identityServiceURL, //"https://identity.ic0.app/"
            maxTimeToLive: BigInt(30 * 60 * 1_000_000_000), // 30 minutes
            onSuccess: () => {
              update((state: AuthStore) => ({
                ...state,
                identity: authClient.getIdentity(),
              }));

              resolve();
            },
            onError: reject,
          });
        });
      }),
```

After doing some research and checking a couple of dapps, it seems like I am forced to use either use an external wallet here or build some sort of own wallet because I cannot reach the “native” wallet. is that correct? If so, I would be interested in the reasoning for this design decision

I want to help, can you help me understand the goal? Abstractly, everything with a principal is a wallet. Principals can be converted to Account Ids, which can have ICP, so a Principal can receive ICP.

Edit: Also, all Principals can have NFTs.

The goal is “simple” :smiley: : I want to have access to the ICP of an authenticated user via Internet Identity.

Setting:
I have an Identity Anchor with X ICP when i log onto the nns dapp.
However, if I use the same Identity Anchor to log into my own dapp, for some reason the identity has a different principal than the one that is shown to me in the nns dapp.

Therefore I can’t access the ICP on the ledger because the different principal leads to a differen accountId.

1 Like

Internet Identity strifes to be an anonymous authentication system, i.e. every application gets a new principal such that the user can’t be correlated. That’s why you have different principals (and hence other ledger accounts) on the NNS dApp and your application.

1 Like