ICP ledger version

I’m a bit confused by the different version of ICP ledger that seem to be available in the dfinity github and described in the token deployment guide. Hopefully, somebody can help here.

  1. Using the “Deploy new token” guide with the latest release version at the time of writing, I get the service part in the candid as below (direct link to candid here, respective wasm would be here)
service : (ledger_arg : LedgerArg) -> {
    icrc1_name : () -> (text) query;
    icrc1_symbol : () -> (text) query;
    icrc1_decimals : () -> (nat8) query;
    icrc1_metadata : () -> (vec record { text; MetadataValue }) query;
    icrc1_total_supply : () -> (Tokens) query;
    icrc1_fee : () -> (Tokens) query;
    icrc1_minting_account : () -> (opt Account) query;
    icrc1_balance_of : (Account) -> (Tokens) query;
    icrc1_transfer : (TransferArg) -> (TransferResult);
    icrc1_supported_standards : () -> (vec record { name : text; url : text }) query;
    get_transactions : (GetTransactionsRequest) -> (GetTransactionsResponse) query;
    get_blocks : (GetBlocksArgs) -> (GetBlocksResponse) query;  
    get_data_certificate : () -> (DataCertificate) query;    
    icrc2_approve : (ApproveArgs) -> (ApproveResult);
    icrc2_allowance : (AllowanceArgs) -> (Allowance) query;
    icrc2_transfer_from : (TransferFromArgs) -> (TransferFromResult);
}

This is implementing the icrc1/2 standards but doesn’t seem to have backwards compatibility with the old ICP ledger version. Also, it’s not running with the Dfinity Rosetta docker, as mentioned here.

  1. When I go directly on github into the icp_ledger repo and look at the ledger.did of the current master branch (link here), I find the following service
service: (LedgerCanisterPayload) -> {
    // Transfers tokens from a subaccount of the caller to the destination address.
    // The source address is computed from the principal of the caller and the specified subaccount.
    // When successful, returns the index of the block containing the transaction.
    transfer : (TransferArgs) -> (TransferResult);

    // Returns the amount of Tokens on the specified account.
    account_balance : (AccountBalanceArgs) -> (Tokens) query;

    // Returns the current transfer_fee.
    transfer_fee : (TransferFeeArg) -> (TransferFee) query;

    // Queries blocks in the specified range.
    query_blocks : (GetBlocksArgs) -> (QueryBlocksResponse) query;

    // Queries encoded blocks in the specified range
    query_encoded_blocks : (GetBlocksArgs) -> (QueryEncodedBlocksResponse) query;
    
    // Returns token symbol.
    symbol : () -> (record { symbol: text }) query;

    // Returns token name.
    name : () -> (record { name: text }) query;

    // Returns token decimals.
    decimals : () -> (record { decimals: nat32 }) query;

    // Returns the existing archive canisters information.
    archives : () -> (Archives) query;

    send_dfx : (SendArgs) -> (BlockIndex);
    account_balance_dfx : (AccountBalanceArgsDfx) -> (Tokens) query;

    // The following methods implement the ICRC-1 Token Standard.
    // https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-1
    icrc1_name : () -> (text) query;
    icrc1_symbol : () -> (text) query;
    icrc1_decimals : () -> (nat8) query;
    icrc1_metadata : () -> (vec record { text; Value }) query;
    icrc1_total_supply : () -> (Icrc1Tokens) query;
    icrc1_fee : () -> (Icrc1Tokens) query;
    icrc1_minting_account : () -> (opt Account) query;
    icrc1_balance_of : (Account) -> (Icrc1Tokens) query;
    icrc1_transfer : (TransferArg) -> (Icrc1TransferResult);
    icrc1_supported_standards : () -> (vec record { name : text; url : text }) query;
    icrc2_approve : (ApproveArgs) -> (ApproveResult);
    icrc2_allowance : (AllowanceArgs) -> (Allowance) query;
}

It’s also including icrc1/2 and seems to have backwards compatibility to previous methods (e.g. transfer). This looks like it reflects also the code in /ledger/src/main.rs of the same repo.
I can even find the method tip_of_chain_pb that is one of the reasons the rosetta docker doesn’t properly run in the other version (point 1 above).

So my questions are

  1. How come the wasm/did of the token deployment guide are not backwards compatible?
  2. Taken the version from the github repo, it seems to be backwards compatible and should also work with rosetta. Is that the case?
  3. How come the two version don’t match? Am I looking at the wrong place in the repository?
  4. Which version should be used to deploy a new custom token (to then also work with rosetta)?

For OGY we use https://github.com/dfinity/ic/tree/master/rs/rosetta-api/icp_ledger

It has this did file that includes the icrc1 and old ledger transfer.

1 Like

The implementation that’s not backwards compatible would be recommended, all new tokens like the SNS tokens should be ICRC-1 without any legacy.

The ICP token has the backwards compatible implementation so it’s backwards compatible with all existing infrastructure that’s already using the ICP token pre ICRC-1 (dapps, rosetta etc).

As for rosetta compatibility with the new standardized ICRC implementation, ICRC standards for transaction history and indexing are work in progress, which are required to make it work with Rosetta.

How come the ICRC1 with legacy is not recommended? Is there any disadvantage to using that version?

This was a personal statement from the viewpoint of reducing implementation complexity and code to maintain and support :sweat_smile:

Also as far as I’m aware the SNS tokens already use the ICRC only implementation.

Indeed, Snses and ckBTC use “only” ICRC.

Are there working Rosetta API docker images for ckBTC and SNS tokens?

I don’t know. I shared your questions with the team so that someone who knows best can answer.

PS: fun fact, I never used myself the Rosetta API :sweat_smile:.

Not at the moment. Rosetta for the icrc1-2 ledgers are on our road map though.