idl2json
idl2json
is a command-line tool used to translate Candid textual values from stdin
into JSON values outputted in stdout
.
idl2json
can be used in workflows where a tool producing Candid values, such as dfx
, needs to provide JSON values to JSON-based tools.
Installation
- Prerequisites
Once you have downloaded cargo, install idl2json
with the cargo install
command:
cargo install idl2json_cli
Usage
To use idl2json
, you must provide standard input to the command in the form of a textual representation of Candid variables. You cannot pass idl2json
binary or hex values.
To demonstrate an example, consider the following 'Hello, world!' actor written in Motoko:
import Debug "mo:base/Debug"
actor HelloWorld {
public func main() {
Debug.print("Hello World!")
}
}
The Candid file for this canister contains the following content:
service : {
main: () -> () oneway;
}
To call this canister's method main
, then convert it into JSON using idl2json
, run the following command:
dfx canister call hello_world main | idl2json
You will receive the following output:
2024-05-21 17:38:29.930244 UTC: [Canister bkyz2-fmaaa-aaaaa-qaaaq-cai] Hello World!
idl2json
can be especially useful to parse and filter large outputs from a canister, such as information about proposals from the NNS canister. For example, consider the following call to the NNS governance canister:
dfx canister call rrkah-fqaaa-aaaaa-aaaaq-cai get_proposal_info '(129396: nat64)' --ic
This call returns a large output that includes the proposal details for proposal 129296. A portion of this output is shown below:
(
opt record {
id = opt record { id = 129_396 : nat64 };
status = 4 : int32;
topic = 8 : int32;
failure_reason = null;
ballots = vec {};
proposal_timestamp_seconds = 1_713_543_513 : nat64;
reward_event_round = 1_080 : nat64;
deadline_timestamp_seconds = opt (1_713_889_113 : nat64);
failed_timestamp_seconds = 0 : nat64;
reject_cost_e8s = 1_000_000_000 : nat64;
derived_proposal_information = null;
latest_tally = opt record {
no = 30_214_275_350_511 : nat64;
yes = 47_423_327_498_625_483 : nat64;
total = 47_711_095_943_759_321 : nat64;
timestamp_seconds = 1_713_886_831 : nat64;
};
reward_status = 3 : int32;
decided_timestamp_seconds = 1_713_779_984 : nat64;
proposal = opt record {
url = "";
title = opt "Upgrade NNS Canister: qoctq-giaaa-aaaaa-aaaea-cai to wasm with hash: c171de6a4e3f7f999829e5ff16d0757f1d0d0bc1730ca24e0fd0f1657f470fad";
action = opt variant {
ExecuteNnsFunction = record {
nns_function = 4 : int32;
...
Then, pass this output to idl2json
:
dfx canister call rrkah-fqaaa-aaaaa-aaaaq-cai get_proposal_info '(129396: nat64)' --ic | idl2json
This output will be quite long as well. A portion of it is shown below for you to compare to the textual Candid representation shown above:
[
{
"ballots": [],
"deadline_timestamp_seconds": [
"1713889113"
],
"decided_timestamp_seconds": "1713779984",
"derived_proposal_information": null,
"executed_timestamp_seconds": "1713779984",
"failed_timestamp_seconds": "0",
"failure_reason": null,
"id": [
{
"id": "129396"
}
],
"latest_tally": [
{
"no": "30214275350511",
"timestamp_seconds": "1713886831",
"total": "47711095943759321",
"yes": "47423327498625483"
}
],
"proposal": [
{
"action": [
{
"ExecuteNnsFunction": {
"nns_function": 4,
"payload": [
68,
73,
68,
76,
4,
...
You can filter this output to get specific information using a command such as:
dfx canister call rrkah-fqaaa-aaaaa-aaaaq-cai get_proposal_info '(129396: nat64)' --ic | idl2json | jq '.[0] | keys'
This filter will return just the top level JSON keys:
[
"ballots",
"deadline_timestamp_seconds",
"decided_timestamp_seconds",
"derived_proposal_information",
"executed_timestamp_seconds",
"failed_timestamp_seconds",
"failure_reason",
"id",
"latest_tally",
"proposal",
"proposal_timestamp_seconds",
"proposer",
"reject_cost_e8s",
"reward_event_round",
"reward_status",
"status",
"topic"
]
dfx
supported JSON output
In dfx
versions 0.19.0
and newer, the flag --output json
can be used with a dfx canister call
command. This removes the need to pipe the output to idl2json
. Learn more in the dfx
documentation.