A Rebel Candid Format

As well as a binary format, Candid possesses a textual presentation, a human-friendly format. We’ve caught glimpses of this format in the input and output of the dfx tool.

But the format is not friendly enough for me:

  • I get confused that some type-related words like record appear before the value, while others like nat8 appear after, and with a colon separator.

  • The sane way to use dfx is to declare Candid interface files in dfx.json, and the textual presentation seems to assume this. However, I like to tinker, and craft messages in the absence of these files.

  • I’m uncertain how Candid’s type inference works. Perhaps I run into trouble because I often neglect to declare Candid interfaces?

  • At times I experiment with messages where most fields have preset values and only a few have varying values. I could use a tool that dumps the hex for the fixed parts.

I devised a rebel textual presentation to address these issues. Thanks to Candid’s elegant design, this is easy to do, especially since I’m only adding features as I need them, rather than supporting the entire spec.


Types go before the value.

nat32 314159



For principal values, use human friendly strings. For example:

principal "fxa77-fiaaa-aaaae-aaana-cai"

encodes to:


Instead of a value, we can place a dollar sign followed by an identifier.

  { memo = nat64 0
  ; amount = record { e8s = nat64 $AMT }
  ; fee = record { e8s = nat64 10000 }
  ; to = blob $TGT
  ; from_subaccount = opt blob $SUB

These variables are enclosed in double quotes and passed through:


Our tool can infer a vector’s type from item values. For example:

  { minting_account = text $MINT_ACC
  ; initial_values = vec
    { record
      { text $ALICE_ACC
      ; record { e8s=nat64 100_000_000_000 }
  ; send_whitelist = vec principal {}