Objective
The goal of developing Canister Metadata Standard is to improve the experience of integrating third party canisters. A service provider make its canister compliant with the standard. Then a consumer can easily pull the canister from the mainnet and set it up locally.
Background
What is Canister Metadata?
Canister is simply a Wasm module. Developer can add arbitrary data to a custom section of the Wasm module. Then the data can be fetched from the metadata
path in system state tree. For more details, please check this section in IC specification.
Why we need a standard?
We plan to provide a complete workflow of third party canister integration for both service provider and consumer. Canister metadata is suitable for communication between the two parties.
The consumer can understand the provider only if they speak “the same language” which is the standard we are proposing.
How will the standard be executed?
In short, dfx
will handle it.
A service provider explicitly opt in this standard by declaring necessary metadata value in dfx.json
. Then dfx
will write metadata in the standard format into Wasm module custom section. When install canister, dfx
will check if the metadata are complaint with the standard in case the developer modify metadata outside dfx
.
A service consumer, declare dependency canister ID in dfx.json
, then dfx
will request the metadata on-chain and setup the dependency canister locally.
Proposal
Before the standard details, I want to state several principles for it:
- Less is more
- No obvious interference with other metadata use cases
- Consider future evolvement
The canister metadata can be viewed as key-value pairs. For simplicity, we only allow valid UTF-8 text in both key and pair.
To avoid name conflicts, we prefix the keys with dfx:
. And all metadata in this standard must have public visibility so that everyone can fetch them.
dfx:wasm_url
A URL to download canister Wasm module which will be deployed locally.
Service provider is responsible for hosting the resource online. When consumer pull the canister, dfx
will check if downloaded wasm hash match on-chain version. If not, a warning message will be shown.
We expect that it will be possible to download canister Wasm directly from IC itself. Then this metadata won’t be required.
dfx:deps
A list of name:ID
pairs of direct dependencies separated by semicolon. This metadata helps resolve transitive dependencies recursively.
For example, if the canister directly depends on:
ledger
canister with mainnet IDbbbbb-bb
;dex
canister with mainnet IDccccc-cc
;
Then the value should be:
ledger:bbbbb-bb;dex:ccccc-cc
;
dfx:init
A message to guide consumers how to initialize this canister.
If it is simple to initialize, the message can be just the command to be executed. If it is complicated, the message can be a URL point to the page with detailed initialization process.
candid:service
The canister interface in candid.
dfx
has supported automatically adding candid:service
metadata. If service provider opt in this standard, this metadata is required to be public.
What next?
We look forward to any comments, questions or feedbacks from the community.
Please note that we are not proposing any new feature to Internet Computer itself. Instead, we are developing a recommended standard for the applications (canisters) on IC. And dfx
will only write these metadata if the provider opt in this approach.
We will stick to current design of the framework. Any suggestion on the details are welcome.
After a short RFC period, we will put this standard in sdk
repo and start implementation soon.
dfx.json
preview
This is just a demo for how would provider/consumer write dfx.json
to interact with canister metadata. It is not a part of the standard.
Provider:
{
"canisters": {
"provider_app": {
...,
"pull": {
"wasm_url": "https://example.com/app.wasm.gz",
"init": "https://example.com/readme.md"
},
"dependencies": [
"ledger", "dex"
]
},
"ledger": ...,
"dex": ...,
}
}
Consumer:
{
"canisters": {
"app": {
...,
"dependencies": [
"provider_app"
]
},
"provider_app": {
type: "pull",
id: "ddddd-dd",
}
}
}