How to convert a principal + subaccount into hexadecimal address (ICP token and ICRC-1)

Please, recommend a Motoko package to convert principal + subaccount into a hexadecimal account address.

I came up with Mops • Motoko Package Manager but it uses a different address format than the NNS Wallet:

assert toText({ owner = Principal.fromText("2chl6-4hpzw-vqaaa-aaaaa-c") }) == "2chl6-4hpzw-vqaaa-aaaaa-c";

I am confused which address format to use: this or NNS wallet. I do want my users easily transfer from NNS Wallet to my app. So, I want hexadecimal. Please, help.

I use this module to convert ICRC accounts to Account Identifier hex, it should work in your case as well.

You can find all imported modules in the same folder in repository.

OK. But is there a package MOPS module that does this?

Probably Principal.toLedgerAccount is what you need?

NNS wallet can send to principals as well as ICRC-1 accounts with subaccount (the bech32 encoded ones). It is not limited to legacy ICP accounts (the hex encoded ones).

I would suggest to show ICRC-1 accounts to the users instead of the hex accounts because then it is consistent for the users across all tokens (ICP and others).

Unless you want users to deposit directly from an exchange (CEX) to your app because most CEX still only understand the legacy hex accounts.

Makes me think that a function Principal.toICRC1Account would also be useful.

1 Like

I think, this is impossible, because I am going to use subaccounts. Is there a format (except that “hex” one) for a principal with a subaccount?

See the docs: ICRC-1 standard specification | Internet Computer

The thread has the history of it if you want some light reading ICRC-1 Account Human Readable Format - #91 by skilesare

2 Likes

What’s your overall setup and goal? Do you have a backend canister that takes deposits from users and issues an individual deposit address to each user? Do you do that for ICP only or also for other tokens?

And does your app consist of frontand and backend?

Can users withdraw as well?

Just wondering what is the total functionality that you need in the end.

Yes to all questions.

Since I have had the exact same problem and probably many other people have to, we have developed a Motoko package for this. Not on mops yet, but in the process of getting there. The package is a class that you use in your canister that issues individual deposit accounts for users, handles all user deposits, consolidates them into a main account, and processes withdrawals from the main account, tracks user credit in the process. It has some advanced features to reduce latency for the user so that the credit can be used as quickly as possible.

It also supports deposits by allowance for users who prefer that.

The package is used in DailyBid (https://alpha.daily-bid.com/). You can try it out there. You don’t need to trade, you can just deposit and withdraw any token to see how the flow works. See this post for an explanation: How to Make Deposits and Withdrawals on the DailyBid Exchange

If it is of interest to you to use this then let me know.

The package is related to the icrc84 standard proposal and is supposed to be the first implementation of it.