Calculating subAccounts from Principal agent-js

Hello Folks,

I’ve been banging my head against a wall trying to get the sub-accounts of a principal in NodeJS using the agent-js lib. I feel like I’m missing something silly as this seems like it should be basic functionality.

I can get the account ID from a principal quite easy using

import { Principal } from "@dfinity/principal";
import { AccountIdentifier } from "@dfinity/nns";

let ID = "XXXXX-XXXXX-..." 
const principal = Principal.from(ID);
const AI = AccountIdentifier.fromPrincipal({ principal });
const AC = AI.toHex();

I’m led to believe that you can add a sub-account parameter to .fromPrincipal({principal, subAccount}) I’ve tried every kind of data type for the subAccount parameter however keep getting the error “TypeError: r.toUint8Array is not a function or its return value is not iterable”

Does anyone have working JS code for getting the sub accounts from a principal?

Thanks in advance!



You can look at how it is done in the nns-dapp:

const principalSubaccount = SubAccount.fromPrincipal(controller);
const accountIdentifier = AccountIdentifier.fromPrincipal({
  principal: swapCanisterId,
  subAccount: principalSubaccount,

From npm i @dfinity/nns

1 Like

To clarify I’m looking to know what type of data is required for subAccount - is it a blob, byte array etc?

1 Like

Thank you @peterparker … now can you transfer all that rust knowledge you have to me? that would be fab :wink:

Haha you won’t go a long way with my noob Rust knowledges :grin:. Happy to hear these links helped.

1 Like

Hi guys, I’m facing a typescript error trying to use the Subaccount and AccountIdentifier classes imports in my react project:

import { AccountIdentifier, SubAccount } from "@dfinity/nns";

After trying to use them like this:

const principalSubaccount = SubAccount.fromPrincipal(controller)
      const accountIdentifier = AccountIdentifier.fromPrincipal({
        principal: principalId,
        subAccount: principalSubaccount

I am getting these ts errors:

'SubAccount' only refers to a type, but is being used as a value here.ts(2693)

Same for AccountIdentifier as well, my typescript skills are still weak, how can I fix this?

So it turns they are now really just types, maybe a latest change? Now how can I get the actual classes?

Which version of @dfinity/nns are you using? Those classes have been moved to @dfinity/ledger-icp for some time now.

Correct import would be:

import { AccountIdentifier, SubAccount } from "@dfinity/ledger-icp";
1 Like

Ah I see it’s because @dfinity/nns also export those with the same name as type, that’s dumb. Legacy inheritance. We should clean that, good catch!

Oh okay, thanks, I was just following this thread, I had installed the latest one, but have just switched to @dfinity/ledger-icp and it’s fixed now. Thank you!

1 Like

Great to hear it works out now!

I’ve taken note that I should have a look at cleaning up those types.

1 Like

I provided a PR #539 this early morning to clean-up those types.