Canister dependency not working?

Hi guys,

Probably a quick one, but I can’t get it working :frowning:

Here’s my dfx.json

{
  "canisters": {
    "internet_identity": {
      "candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did",
      "frontend": {},
      "remote": {
        "id": {
          "ic": "rdmx6-jaaaa-aaaaa-aaadq-cai"
        }
      },
      "type": "custom",
      "wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz"
    },
    "icp_ledger_canister": {
      "type": "custom",
      "candid": "https://raw.githubusercontent.com/dfinity/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/rs/rosetta-api/icp_ledger/ledger.did",
      "wasm": "https://download.dfinity.systems/ic/ec35ebd252d4ffb151d2cfceba3a86c4fb87c6d6/canisters/ledger-canister.wasm.gz",
      "remote": {
        "id": {
          "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
        }
      }
    },
    "myapp_backend": {
      "main": "src/myapp_backend/main.mo",
      "type": "motoko",
      "dependencies": [
          "icp_ledger_canister"
      ]
    },
    "myapp_frontend": {
      "dependencies": [
        "myapp_backend"
      ],
      "source": [
        "src/myapp_frontend/dist"
      ],
      "type": "assets",
      "workspace": "myapp_frontend"
    }
  },
  "defaults": {
    "build": {
      "args": "",
      "packtool": ""
    }
  },
  "output_env_file": ".env",
  "version": 1
}

However in my main.mo

I’ve tried to run dfx deploy. I’ve tried to restart my VSCode. Nothing fixes it and I’m out of ideas.
(Also, I don’t see any difference between my code and this sample code).

Any help appreciated!

If you want to intercact with ICP ledger, import the types into your motoko from https://dashboard.internetcomputer.org/canister/ryjl3-tyaaa-aaaaa-aaaba-cai

and define icp actor, then start working with that.

example:
create a motoko file for putting icp actor types.
icp_types.mo


module {
  public type Account = { owner : Principal; subaccount : ?Blob };
  public type AccountBalanceArgs = { account : Text };
  public type Allowance = { allowance : Nat; expires_at : ?Nat64 };
  public type AllowanceArgs = { account : Account; spender : Account };
  public type ApproveArgs = {
    fee : ?Nat;
    memo : ?Blob;
    from_subaccount : ?Blob;
    created_at_time : ?Nat64;
    amount : Nat;
    expected_allowance : ?Nat;
    expires_at : ?Nat64;
    spender : Account;
  };
  public type ApproveError = {
    #GenericError : { message : Text; error_code : Nat };
    #TemporarilyUnavailable;
    #Duplicate : { duplicate_of : Nat };
    #BadFee : { expected_fee : Nat };
    #AllowanceChanged : { current_allowance : Nat };
    #CreatedInFuture : { ledger_time : Nat64 };
    #TooOld;
    #Expired : { ledger_time : Nat64 };
    #InsufficientFunds : { balance : Nat };
  };
  public type ArchiveInfo = { canister_id : Principal };
  public type ArchiveOptions = {
    num_blocks_to_archive : Nat64;
    max_transactions_per_response : ?Nat64;
    trigger_threshold : Nat64;
    max_message_size_bytes : ?Nat64;
    cycles_for_archive_creation : ?Nat64;
    node_max_memory_size_bytes : ?Nat64;
    controller_id : Principal;
  };
  public type ArchivedBlocksRange = {
    callback : shared query GetBlocksArgs -> async Result_3;
    start : Nat64;
    length : Nat64;
  };
  public type ArchivedEncodedBlocksRange = {
    callback : shared query GetBlocksArgs -> async Result_4;
    start : Nat64;
    length : Nat64;
  };
  public type Archives = { archives : [ArchiveInfo] };
  public type BinaryAccountBalanceArgs = { account : Blob };
  public type BlockRange = { blocks : [CandidBlock] };
  public type CandidBlock = {
    transaction : CandidTransaction;
    timestamp : TimeStamp;
    parent_hash : ?Blob;
  };
  public type CandidOperation = {
    #Approve : {
      fee : Tokens;
      from : Blob;
      allowance_e8s : Int;
      allowance : Tokens;
      expected_allowance : ?Tokens;
      expires_at : ?TimeStamp;
      spender : Blob;
    };
    #Burn : { from : Blob; amount : Tokens; spender : ?Blob };
    #Mint : { to : Blob; amount : Tokens };
    #Transfer : {
      to : Blob;
      fee : Tokens;
      from : Blob;
      amount : Tokens;
      spender : ?Blob;
    };
  };
  public type CandidTransaction = {
    memo : Nat64;
    icrc1_memo : ?Blob;
    operation : ?CandidOperation;
    created_at_time : TimeStamp;
  };
  public type Decimals = { decimals : Nat32 };
  public type Duration = { secs : Nat64; nanos : Nat32 };
  public type FeatureFlags = { icrc2 : Bool };
  public type GetBlocksArgs = { start : Nat64; length : Nat64 };
  public type GetBlocksError = {
    #BadFirstBlockIndex : {
      requested_index : Nat64;
      first_valid_index : Nat64;
    };
    #Other : { error_message : Text; error_code : Nat64 };
  };
  public type InitArgs = {
    send_whitelist : [Principal];
    token_symbol : ?Text;
    transfer_fee : ?Tokens;
    minting_account : Text;
    maximum_number_of_accounts : ?Nat64;
    accounts_overflow_trim_quantity : ?Nat64;
    transaction_window : ?Duration;
    max_message_size_bytes : ?Nat64;
    icrc1_minting_account : ?Account;
    archive_options : ?ArchiveOptions;
    initial_values : [(Text, Tokens)];
    token_name : ?Text;
    feature_flags : ?FeatureFlags;
  };
  public type LedgerCanisterPayload = {
    #Upgrade : ?UpgradeArgs;
    #Init : InitArgs;
  };
  public type MetadataValue = {
    #Int : Int;
    #Nat : Nat;
    #Blob : Blob;
    #Text : Text;
  };
  public type Name = { name : Text };
  public type QueryBlocksResponse = {
    certificate : ?Blob;
    blocks : [CandidBlock];
    chain_length : Nat64;
    first_block_index : Nat64;
    archived_blocks : [ArchivedBlocksRange];
  };
  public type QueryEncodedBlocksResponse = {
    certificate : ?Blob;
    blocks : [Blob];
    chain_length : Nat64;
    first_block_index : Nat64;
    archived_blocks : [ArchivedEncodedBlocksRange];
  };
  public type Result = { #Ok : Nat; #Err : TransferError };
  public type Result_1 = { #Ok : Nat; #Err : ApproveError };
  public type Result_2 = { #Ok : Nat; #Err : TransferFromError };
  public type Result_3 = { #Ok : BlockRange; #Err : GetBlocksError };
  public type Result_4 = { #Ok : [Blob]; #Err : GetBlocksError };
  public type Result_5 = { #Ok : Nat64; #Err : TransferError_1 };
  public type SendArgs = {
    to : Text;
    fee : Tokens;
    memo : Nat64;
    from_subaccount : ?Blob;
    created_at_time : ?TimeStamp;
    amount : Tokens;
  };
  public type StandardRecord = { url : Text; name : Text };
  public type Symbol = { symbol : Text };
  public type TimeStamp = { timestamp_nanos : Nat64 };
  public type Tokens = { e8s : Nat64 };
  public type TransferArg = {
    to : Account;
    fee : ?Nat;
    memo : ?Blob;
    from_subaccount : ?Blob;
    created_at_time : ?Nat64;
    amount : Nat;
  };
  public type TransferArgs = {
    to : Blob;
    fee : Tokens;
    memo : Nat64;
    from_subaccount : ?Blob;
    created_at_time : ?TimeStamp;
    amount : Tokens;
  };
  public type TransferError = {
    #GenericError : { message : Text; error_code : Nat };
    #TemporarilyUnavailable;
    #BadBurn : { min_burn_amount : Nat };
    #Duplicate : { duplicate_of : Nat };
    #BadFee : { expected_fee : Nat };
    #CreatedInFuture : { ledger_time : Nat64 };
    #TooOld;
    #InsufficientFunds : { balance : Nat };
  };
  public type TransferError_1 = {
    #TxTooOld : { allowed_window_nanos : Nat64 };
    #BadFee : { expected_fee : Tokens };
    #TxDuplicate : { duplicate_of : Nat64 };
    #TxCreatedInFuture;
    #InsufficientFunds : { balance : Tokens };
  };
  public type TransferFee = { transfer_fee : Tokens };
  public type TransferFromArgs = {
    to : Account;
    fee : ?Nat;
    spender_subaccount : ?Blob;
    from : Account;
    memo : ?Blob;
    created_at_time : ?Nat64;
    amount : Nat;
  };
  public type TransferFromError = {
    #GenericError : { message : Text; error_code : Nat };
    #TemporarilyUnavailable;
    #InsufficientAllowance : { allowance : Nat };
    #BadBurn : { min_burn_amount : Nat };
    #Duplicate : { duplicate_of : Nat };
    #BadFee : { expected_fee : Nat };
    #CreatedInFuture : { ledger_time : Nat64 };
    #TooOld;
    #InsufficientFunds : { balance : Nat };
  };
  public type UpgradeArgs = {
    maximum_number_of_accounts : ?Nat64;
    icrc1_minting_account : ?Account;
    feature_flags : ?FeatureFlags;
  };
  public type icpActor = LedgerCanisterPayload -> async actor {
    account_balance : shared query BinaryAccountBalanceArgs -> async Tokens;
    account_balance_dfx : shared query AccountBalanceArgs -> async Tokens;
    account_identifier : shared query Account -> async Blob;
    archives : shared query () -> async Archives;
    decimals : shared query () -> async Decimals;
    icrc1_balance_of : shared query Account -> async Nat;
    icrc1_decimals : shared query () -> async Nat8;
    icrc1_fee : shared query () -> async Nat;
    icrc1_metadata : shared query () -> async [(Text, MetadataValue)];
    icrc1_minting_account : shared query () -> async ?Account;
    icrc1_name : shared query () -> async Text;
    icrc1_supported_standards : shared query () -> async [StandardRecord];
    icrc1_symbol : shared query () -> async Text;
    icrc1_total_supply : shared query () -> async Nat;
    icrc1_transfer : shared TransferArg -> async Result;
    icrc2_allowance : shared query AllowanceArgs -> async Allowance;
    icrc2_approve : shared ApproveArgs -> async Result_1;
    icrc2_transfer_from : shared TransferFromArgs -> async Result_2;
    name : shared query () -> async Name;
    query_blocks : shared query GetBlocksArgs -> async QueryBlocksResponse;
    query_encoded_blocks : shared query GetBlocksArgs -> async QueryEncodedBlocksResponse;
    send_dfx : shared SendArgs -> async Nat64;
    symbol : shared query () -> async Symbol;
    transfer : shared TransferArgs -> async Result_5;
    transfer_fee : shared query {} -> async TransferFee;
  }
}

Then import all the types declared in icp_types.mo into your main.mo file

// Import icp ledger types from icp_types.mo
import icpTypes  "icp_types";

// Create ICP actor to make calls to icp canister
let icpActor : icpTypes.icpActor = actor (Principal.fromText("ryjl3-tyaaa-aaaaa-aaaba-cai"));

// Exmaple call 
 let transferArgs : icpTypes.TransferArgs = {
      to : icpTypes.Account = {
           owner = //Users principal address;
           subaccount = null;
      };
      from_subaccount=null;
      amount = //Amount to be transferred;
    };
let result: icpTypes.Result = await icpActor.icrc1_transfer(transferArgs);

1 Like

To clarify: This is only a problem in VSCode, not when actually dfx deploying, correct? I have the same problem but keep ignoring it. @rvanasa, can you help?

Yes, exactly. No error when I dfx deploy. It crossed my mind that it could be just a VSCode issue, hence

but I wasn’t sure.

About:

thing is, when I have this VSCode error, all other errors are ignored (as in not displayed). In other words, it would mean developing blind.

(Replied in the corresponding GitHub issue)

1 Like

@rvanasa I saw your last reply from a few hours ago, but I’m not in front of the computer right now. I’ll reply ASAP.

Another lead could be that @Severin appears to experience the same issue.