ICRC-1: Where can I find the ICR1 implementation ledger code? I need the installation argument struct

I’m using this configuration in my dfx.json.

    "icrc1_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz",
      "remote": {
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }
    }

However, the issue that I have is that there’s a mismatch between the types in my ICRC1 deployment installation arguments. Note: I’m using PocketIC to test the deployment.

 let icrc1_deploy_args = ICRC1Args::Init(ICRC1InitArgs {
            token_symbol: "MCK".to_string(),
            token_name: "Mock Token".to_string(),
            minting_account: Account {
                owner: caller,
                subaccount: None,
            },
            transfer_fee: candid::Nat(1_000_000.to_biguint().unwrap()),
            metadata: vec![],
            initial_balances: vec![
                (
                    Account {
                        owner: caller,
                        subaccount: None,
                    },
                    candid::Nat(mint_amount.to_biguint().unwrap()),
                ),
            ],
            archive_options: ArchiveOptions {
                num_blocks_to_archive: candid::Nat(10.to_biguint().unwrap()),
                trigger_threshold: candid::Nat(5.to_biguint().unwrap()),
                controller_id: caller,
                max_transactions_per_response: None,
                max_message_size_bytes: None,
                cycles_for_archive_creation: None,
                node_max_memory_size_bytes: None,
            },
            feature_flags: Some(FeatureFlags { icrc2: false }),
            decimals: Some(candid::Nat(3.to_biguint().unwrap())),  // Assuming 8 decimals, adjust as needed
            maximum_number_of_accounts: None,
            accounts_overflow_trim_quantity: None,
            fee_collector_account: None,
            max_memo_length: None,
        });

        pic.install_canister(icrc_ledger, icrc_wasm_module, encode_one(icrc1_deploy_args).unwrap(), Some(caller));

The error I am getting is the following:

thread 'tests::intent_tests::should_transfer_icrc1' panicked at /Users/vincxntes/.cargo/registry/src/index.crates.io-6f17d22bba15001f/pocket-ic-5.0.0/src/nonblocking.rs:840:10:
called `Result::unwrap()` on an `Err` value: UserError(UserError { code: CanisterCalledTrap, description: "Error from Canister lqy7q-dh777-77777-aaaaq-cai: Canister called `ic0.trap` with message: failed to decode call arguments: Custom(Fail to decode argument 0 from table0 to variant {\n  Upgrade : opt record {\n    token_symbol : opt text;\n    transfer_fee : opt nat;\n    metadata : opt vec record {\n      text;\n      variant { Int : int; Nat : nat; Blob : vec nat8; Text : text };\n    };\n    maximum_number_of_accounts : opt nat64;\n    accounts_overflow_trim_quantity : opt nat64;\n    change_fee_collector : opt variant {\n      SetTo : record { owner : principal; subaccount : opt vec nat8 };\n      Unset;\n    };\n    max_memo_length : opt nat16;\n    token_name : opt text;\n    feature_flags : opt record { icrc2 : bool };\n  };\n  Init : record {\n    decimals : opt nat8;\n    token_symbol : text;\n    transfer_fee : nat;\n    metadata : vec record {\n      text;\n      variant { Int : int; Nat : nat; Blob : vec nat8; Text : text };\n    };\n    minting_account : record { owner : principal; subaccount : opt vec nat8 };\n    initial_balances : vec record {\n      record { owner : principal; subaccount : opt vec nat8 };\n      nat;\n    };\n    maximum_number_of_accounts : opt nat64;\n    accounts_overflow_trim_quantity : opt nat64;\n    fee_collector_account : opt record {\n      owner : principal;\n      subaccount : opt vec nat8;\n    };\n    archive_options : record {\n      num_blocks_to_archive : nat64;\n      max_transactions_per_response : opt nat64;\n      trigger_threshold : nat64;\n      max_message_size_bytes : opt nat64;\n      cycles_for_archive_creation : opt nat64;\n      node_max_memory_size_bytes : opt nat64;\n      controller_id : principal;\n    };\n    max_memo_length : opt nat16;\n    token_name : text;\n    feature_flags : opt record { icrc2 : bool };\n  };\n}\n\nCaused by:\n    0: input: 4449444c156b02fcb88b840301b0ced18403106c099efeb9a40302f2c794ae0303efcee780040497aabdbb06038484d5c0070385f199f40709b0d7c3920b0d91c9aafe0d02bea3d1c30f0e6e716e7d6e056d066c02007101076b04cf89df017cc189ee017dfdd2c9df0208cdf1cbbe03716d7b6e0a6b029d83f46a0bc9c5f1d0037f6c02b3b0dac30368ad86ca83050c6e086e7a6e0f6c01c7bfe7b60b7e6c0dc295a99301039efeb9a40371f2c794ae037defcee7800405aecbeb88040bb2a4dab2051197aabdbb06038484d5c0070382babe820813a1e5f7a10a14b0d7c3920b0391c9aafe0d71bea3d1c30f0e6d126c02000b017d6e0b6c079ea581d2017db2a7c2d20303a495a5e9067de0ab86ef0803e4d8cce80b0393c8e6c70c03dec5d8ae0e680100010103034d434bc0843d00011dcc9ac7f36ced820f399b6e7a16eaac06a04aea82cc55917650270bdc020001011dcc9ac7f36ced820f399b6e7a16eaac06a04aea82cc55917650270bdc020080d0dbc3f402000000_0a0005000000011dcc9ac7f36ced820f399b6e7a16eaac06a04aea82cc55917650270bdc02000a4d6f636b20546f6b656e0100\n       table: type table0 = variant { 813_882_492 : table1; 815_032_112 : table16 }\n       type table1 = record {\n         881_753_886 : table2;\n         902_112_242 : table3;\n         1_075_439_471 : table4;\n         1_735_349_527 : table3;\n         2_014_659_076 : table3;\n         2_122_741_893 : table9;\n         2_991_647_664 : table13;\n         3_754_599_569 : table2;\n         4_168_372_670 : table14;\n       }\n       type table10 = variant { 224_199_069 : table11; 974_938_825 }\n       type table11 = record { 947_296_307 : principal; 1_349_681_965 : table12 }\n       type table12 = opt table8\n       type table13 = opt nat16\n       type table14 = opt table15\n       type table15 = record { 3_067_731_911 : bool }\n       type table16 = record {\n         308_955_842 : table3;\n         881_753_886 : text;\n         902_112_242 : nat;\n         1_075_439_471 : table5;\n         1_092_281_774 : table11;\n         1_448_514_098 : table17;\n         1_735_349_527 : table3;\n         2_014_659_076 : table3;\n         2_152_701_186 : table19;\n         2_755_523_233 : table20;\n         2_991_647_664 : table3;\n         3_754_599_569 : text;\n         4_168_372_670 : table14;\n       }\n       type table17 = vec table18\n       type table18 = record { table11; nat }\n       type table19 = opt table11\n       type table2 = opt text\n       type table20 = record {\n         440_423_070 : nat;\n         978_359_218 : table3;\n         1_831_422_628 : nat;\n         2_380_371_424 : table3;\n         3_172_150_372 : table3;\n         3_371_803_667 : table3;\n         3_856_016_094 : principal;\n       }\n       type table3 = opt nat\n       type table4 = opt table5\n       type table5 = vec table6\n       type table6 = record { text; table7 }\n       type table7 = variant {\n         3_654_863 : int;\n         3_900_609 : nat;\n         737_307_005 : table8;\n         936_573_133 : text;\n       }\n       type table8 = vec nat8\n       type table9 = opt table10\n       wire_type: nat, expect_type: nat64\n    1: Subtyping error: TypeInner :: Nat64).\nConsider gracefully handling failures from this canister or altering the canister to handle exceptions. See documentation: http://internetcomputer.org/docs/current/references/execution-errors#trapped-explicitly" })

TLDR: The error seems to be caused by a mismatch between the expected and actual data types:

  • Wire Type: nat
  • Expected Type: nat64

My current installation struct (coded based on my interpretion of these type mismatch errors)

#[derive(CandidType, Serialize, Deserialize, Clone, Debug)]
pub enum ICRC1Args {
    Init(ICRC1InitArgs),
    Upgrade(ICRC1UpgradeArgs),
}

#[derive(CandidType, Serialize, Deserialize, Clone, Debug)]
pub struct ICRC1InitArgs {
    pub token_symbol: String,
    pub token_name: String,
    pub minting_account: Account,
    pub transfer_fee: Nat,
    pub metadata: Vec<(String, MetadataValue)>,
    pub initial_balances: Vec<(Account, Nat)>,
    pub archive_options: ArchiveOptions,
    pub feature_flags: Option<FeatureFlags>,
    pub decimals: Option<candid::Nat>,
    pub maximum_number_of_accounts: Option<candid::Nat>,
    pub accounts_overflow_trim_quantity: Option<candid::Nat>,
    pub fee_collector_account: Option<Account>,
    pub max_memo_length: Option<candid::Nat>,
}

I need to get the actual struct defined in the coded canister (the one retrieved via the dfx.json) so that I can use that for my installation arguments in my PocketIC tests.

Hello @vincentes , i think this should help :

What type do I use in Rust for candid nat64? I’m using nat and it’s saying that there’s a type mismatch between nat and nat64.

https://internetcomputer.org/docs/current/references/candid-ref#type-natn-and-intn

u64 should be the Rust equivalent of candid nat64.

1 Like