Simplest / best way to make inter-canister calls in Motoko

What’s the simplest / best way to make inter-canister calls in Motoko?

I tried the pattern here: linkedup/main.mo at master · dfinity/linkedup · GitHub

But on deployment of the canister that has the import statement, I get

import error [M0011], canister alias "canister_name" not defined

Despite dfx.json including it in the canister list, and indeed “canister_name” itself being already deployed on the local replica.

Did you add the canister in the dependencies list? Like here: linkedup/dfx.json at master · dfinity/linkedup · GitHub

let canisterB = actor ("canister_id") : actor {
      service : (Text, Int, ....) -> async (Text);
//you can define as many services here.
};

//Calling
let t : Text = await canisterB.service(arg1, arg2);

//Make canisterB instance like above in any other canisterA like this. 
2 Likes

Yes, it turns out the problem was class actor canisters can’t be imported with canister:, which is the only way I found the docs and examples made reference to:

By using the service pattern, it worked. In my case:

let icrc_token_canister = actor ("r7inp-6aaaa-aaaaa-aaabq-cai") : ICRCTypes.TokenInterface;

@Severin If you have any say in the docs / examples, I suggest making clear that

import AAA "canister:aaa";

does not and cannot work with class actors. I spent quite a while trying to make canister: work yesterday.

4 Likes

In case you haven’t found the relevant documentation, here are some links.

Apologies if it’s not clear enough.

Intro discussion

Reference material:

Imports

Libraries and actor classes

There seems to be guidance on how to create a new class actor canister from inside another canister but not on how to simply call a deployed class actor canister from another canister, eg how to achieve the last line here:

let icrc_canister = actor ("r7inp-6aaaa-aaaaa-aaabq-cai") : ICRCTypes.TokenInterface;

let token_symbol = await icrc_canister.icrc1_symbol();

In particular, no mention that canister: only works for certain types of canisters (non-class-actor canisters), which was the main cause for my confusion:

I assume the confusion would not arise if I had a deeper understanding of the complete IC but at least for me, it arose.

That’s useful feedback, thanks!

We do have a related sample here examples/motoko/actor_reference at master · dfinity/examples · GitHub

But that’s obviously too hard to find and should be covered more directly in the doc.

2 Likes

Those URLs too seem broken, I experienced something similar with a link to the docs posted by Kyle. Can we fix this?

1 Like

We just had a major redesign of the docs and there will be a lot more broken links. I just fixed the ones you pointed out, but please keep reporting them

2 Likes

Agree that its way too hard to find a simple example of doing intercanister call to a mainnet canister
Don’t even get me started on doing candid to motoko type translation

1 Like

In particular, no mention that canister: only works for certain types of canisters (non-class-actor canisters).

That’s wrong. Indeed, canister: does work for class actor canisters (I use it all the time), provided that you have it deployed with appropriate args.

I think the point was that when you receive like that you can’t use that to spawn a canister of the same type(because all you end up with is the interface and not the wasm).