How to make IC Management API canister_status call with @dfinity/agent?

Late to the party but since I implemented this today here’s my solution.

  1. Get the interface spec - the id.did file
  2. Generate did.d.ts and did.js from Candid file, for example with Canlista UI
  3. The typescript code:
import {CallConfig, Identity} from '@dfinity/agent';
import {Principal} from '@dfinity/principal';
import {_SERVICE as IcManagerActor} from '../../canisters/ic/ic.did';
import {idlFactory as IcManagerFactory} from '../../canisters/ic/ic.utils.did';
import {createActor} from '../../utils/actor.utils';
import {getIdentity} from '../auth/auth.providers';

const MANAGEMENT_CANISTER_ID = Principal.fromText('aaaaa-aa');

// Source nns-dapp - dart -> JS bridge
const transform = (_methodName: string, args: unknown[], _callConfig: CallConfig) => {
  const first = args[0] as any;
  let effectiveCanisterId = MANAGEMENT_CANISTER_ID;
  if (first && typeof first === 'object' && first.canister_id) {
    effectiveCanisterId = Principal.from(first.canister_id as unknown);
  }
  return {effectiveCanisterId};
};

const createIcManagerActor = ({identity}: {identity: Identity}): Promise<IcManagerActor> => {
  return createActor<IcManagerActor>({
    config: {
      canisterId: MANAGEMENT_CANISTER_ID,
      callTransform: transform,
      queryTransform: transform
    },
    idlFactory: IcManagerFactory,
    identity
  });
};

export const canisterStatus = async (canisterId: string) => {
  // authClient?.getIdentity();
  const identity: Identity | undefined = getIdentity();

  if (!identity) {
    throw new Error('No internet identity to get canister status');
  }

  const actor: IcManagerActor = await createIcManagerActor({identity});

  const response = await actor.canister_status({
    canister_id: Principal.fromText(canisterId)
  });

  console.log(response);

  // note: if error 403 => user is not the controller of the canister
};

Note: I assume it works out. At the end of the day I am not going to use following code for my app because your identity needs to be the controller for the canister to query it which is not my use case :crazy_face:

4 Likes