In Joachim Breitner’s last blog on Candid he ends with this:
Self-describing Services
As you have noticed, Candid was very much designed assuming that all parties always have the service type of services they want to interact with. But the Candid specification does not define how one can obtain the interface of a given service, and there isn’t really a an official way to do that on the Internet Computer.
That is unfortunate, because many interesting features depend on that: Such as writing
import C "ic:7e6iv-biaaa-aaaaf-aaada-cai"
in your Motoko program, and having it’s type right there. Or tools like ic.rocks, that allow you to interact with any canister right there.One reason why we don’t really have that feature yet is because of disagreements about how dynamic that feature should be. Should you be able to just ask the canister for its interface (and allow the canister to vary the response, for example if it can change its functionality over time, even without changing the actual wasm code)? Or is the interface a static property of the code , and one should be able to query the system for that data, without the canister’s active involvement. Or, completely different, should interfaces be distributed out of band, maybe together with API documentation, or in some canister registry somewhere else?
I always leaned towards the first of these options, but not convincingly enough. The second options requires system assistance, so more components to change, more teams to be involved that maybe intrinsically don’t care a lot about this feature. And the third might have emerged as the community matures and builds such infrastructure, but that did not happen yet.
In the end I sneaked in an implementation of the first into Motoko, arguing that even if we don’t know yet how this feature will be implemented eventually, we all want the feature to exist somehow, and we really really want to unblock all the interesting applications it enables (e.g. Candid UI). That’s why every Motoko canister, and some rust canisters too, implements a method
__get_candid_interface_tmp_hack : () -> (text)
that one can use to get the Candid interface file.
The name was chosen to signal that this may not be the final interface, but like all good provisional solutions, it may last longer than intended. If that’s the case, I’m not sorry.
I actually thought because of things like candidUI and ICRocks that option 1 was already the case. I am working on an application myself where I want to be able to call
functions on canister A from canister B without knowing in advance what those functions will be.
In general it seems like a really nice thing to have from the perspective of creating composable services on the IC. An example usecase that I can think of is downloading the interface of a service and mocking it for local development even if the code is not open sourced.
I would love to hear the thoughts from the foundation and community around this topic. In the meanwhile I will always put __get_candid_interface_tmp_hack : () -> (text)
in my rust canisters and I hope everyone else will do the same.