Generate unique ICRC-1 address for each user (subaccount)

Hi,

I am trying to generate a unique address (principal) for each user so I can display it in the front end and the user can send ckBTC token to this address.

I tried to search for solutions and couldn’t find any. The closest I got was with this code that I found in this thread:

  public type Account = { owner : Principal; subaccount : ?Blob };

  public shared (msg) func getDepositAddress() : async Text {
    let acc : Account = {
      owner = Principal.fromActor(this);
      subaccount = ?Principal.toBlob(msg.caller);
    };
    return Account.toText(acc);
  };

However, it is trapping when I call the function because of this assertion in the Account.mo module.

assert (subaccount.size() == 32);

Please, do you have a working example somewhere? I feel like this should be really straightforward but I spent a couple of hours on it and couldn’t find a solution for this use case.

1 Like

The principal is up to 29 bytes, that’s why the assertion failed
You can try: toSubAccount

2 Likes

Thanks a lot @zohaib29, this works for me. I put together a small working example that generates subaccount for each caller and then verifies balance of it in case this can be helpful for anyone:

1 Like