Minting account <none>

When I deploy locally the CMC using JavaScript, the CMC prints following message:

2024-05-12 19:46:32.120446192 UTC: [Canister rkp4c-7iaaa-aaaaa-aaaca-cai] [cycles] init() with ledger canister ryjl3-tyaaa-aaaaa-aaaba-cai, governance canister rrkah-fqaaa-aaaaa-aaaaq-cai, exchange rate canister , and minting account

i.e. it informs me that the minting account is none however, from types and code perspective, everything seems fine on my hand.

const minterAccountIdentifier = AccountIdentifier.fromPrincipal({
      principal: minterIdentity.getPrincipal()
    });

    console.log('-------------------->', minterAccountIdentifier, minterAccountIdentifier.toHex());

    const sourceArg: CyclesCanisterInitPayload = {
      exchange_rate_canister: [],
      last_purged_notification: [0n],
      governance_canister_id: [Principal.fromText(governanceCanisterId)],
      minting_account_id: [{bytes: minterAccountIdentifier.toUint8Array()}],
      ledger_canister_id: [Principal.fromText(icpLedgerCanisterId)]
    };

// Type definitions generated by Candid are not clean enough.
    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
    const arg = IDL.encode(init({IDL}), [[sourceArg]]);

The above printing an account identifier equals to:

--------------------> By {
bytes: Uint8Array(32) [
41, 192, 86, 134, 16, 164, 21, 239,
235, 244, 103, 115, 119, 41, 65, 99,
255, 184, 34, 109, 71, 61, 173, 184,
117, 150, 212, 221, 164, 135, 4, 71
]
} 29c0568610a415efebf4677377294163ffb8226d473dadb87596d4dda4870447

The minter account identifier toUint8Array provides the bytes

public toUint8Array(): Uint8Array {
    return this.bytes;
  }

And the candid definition of the CMC also expect bytes

export interface AccountIdentifier {
  bytes: Uint8Array | number[];
}

So I’m a bit confuse about the issue. Is it possible that the CMC did file is incorrect and its Accountidentifier should actually be encoded differently?

type AccountIdentifier = record {
  bytes: blob;
};

type CyclesCanisterInitPayload = record {
    ledger_canister_id: opt principal;
    governance_canister_id: opt principal;
    minting_account_id: opt AccountIdentifier;
    last_purged_notification: opt nat64;
    exchange_rate_canister: opt ExchangeRateCanister;
};

The cmc did file in the ic git repo shows that AccountIdentifier is a text

It is the text of the hexadecimal string of the 32-byte-account-identifier

1 Like

Thanks for the hint. I’m using commit 6223a38cfae726e9cc83db9ae27f35ca979dd0d8 in which its a blob. Maybe this version uses protobuf. So I either need to try to upgrade or serialize the init payload with it. Will try one or the other later.

Bumping the CMC version to most recent proposed commit hash e790c6636115482db53ca3daa2f1900202ab04cf and adapting the account identifier to pass an optional text resolves the issue.

[cycles] init() with ledger canister ryjl3-tyaaa-aaaaa-aaaba-cai, governance canister rrkah-fqaaa-aaaaa-aaaaq-cai, exchange rate canister , minting account dfba96d057c9da2dabbc15a424a7da2ad5840aa995e4f5ab0cdb9e4792dea628, and cycles ledger canister

If it can help anyone in the future, the implementation of the related module in the embededded CLI of Juno’s Docker:

import {IDL} from '@dfinity/candid';
import {Principal} from '@dfinity/principal';
import {assertNonNullish} from '@dfinity/utils';
import {AccountIdentifier} from '@junobuild/ledger';
import {MINTER_IDENTITY_KEY} from '../constants/constants';
import type {CyclesCanisterInitPayload} from '../declarations/cmc';
import {init} from '../declarations/cmc.idl';
import {Module} from '../services/modules.services';
import type {ModuleDescription, ModuleInstallParams} from '../types/module';

const CMC: ModuleDescription = {
  key: 'cmc',
  name: 'CMC',
  canisterId: 'rkp4c-7iaaa-aaaaa-aaaca-cai'
};

class CmcModule extends Module {
  override async install({state, identities, ...rest}: ModuleInstallParams): Promise<void> {
    const icpLedgerCanisterId = state.getModule('icp_ledger')?.canisterId;

    assertNonNullish(
      icpLedgerCanisterId,
      'Cannot configure CMC because the ICP ledger id is unknown.'
    );

    const governanceCanisterId = state.getModule('governance')?.canisterId;

    assertNonNullish(
      governanceCanisterId,
      'Cannot configure CMC because the NNS Governance id is unknown.'
    );

    const {[MINTER_IDENTITY_KEY]: minterIdentity} = identities;

    const minterAccountIdentifier = AccountIdentifier.fromPrincipal({
      principal: minterIdentity.getPrincipal()
    });

    const sourceArg: CyclesCanisterInitPayload = {
      exchange_rate_canister: [],
      last_purged_notification: [0n],
      governance_canister_id: [Principal.fromText(governanceCanisterId)],
      minting_account_id: [minterAccountIdentifier.toHex()],
      ledger_canister_id: [Principal.fromText(icpLedgerCanisterId)],
      cycles_ledger_canister_id: []
    };

    // Type definitions generated by Candid are not clean enough.
    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
    const arg = IDL.encode(init({IDL}), [[sourceArg]]);

    await super.install({
      state,
      arg,
      identities,
      ...rest
    });
  }
}

export const cmc = new CmcModule(CMC);

Thanks again for the hint @levi .

1 Like