ICRC icon indicating copy to clipboard operation
ICRC copied to clipboard

ICRC-30: JSON type syntax for Candid values

Open sea-snake opened this issue 2 years ago • 4 comments

When communicating Candid data with JSON between web services, there are two options:

  • CBOR encode to bytes and send as JSON text value (base64/hex)
  • Write Candid data with a JSON syntax

The latter is more accessible to services and dapps outside the IC ecosystem, they don't need to understand and decode CBOR to process incoming data.

A few examples:

  • JSON-RPC between dapps and (multi chain) wallets with ICRC-25
  • canisters with public HTTP APIs accepting and returning JSON for dapps outside the IC ecosystem that want to query their data.
  • Browser messaging and storage of Candid types

This standard standardizes the JSON syntax of Candid type values for above use cases with a strong emphasis on making the data accessible for dapps outside the IC ecosystem without Candid knowledge.

The following technical details differ from other encoding formats of Candid types like CBOR:

  • JSON values represent the most straightforward representation of the value.
  • JSON values do only partially represent the Candid type, the consuming party is expected to know the Candid types in cases where its needed.
  • JSON values for the opt type differ depending on where its used, if possible without losing structural information, null values are left out of the JSON string.
  • JSON values are structured to have a minimal footprint and to be straightforward for consuming services outside the IC ecosystem without requiring knowledge of Candid.

The spec can be found at the following gist (until I've found a better place for it): https://gist.github.com/sea-snake/3043a9b83348111326a7699efb97e281

sea-snake avatar Sep 09 '23 12:09 sea-snake

Some topics of discussion:

  • JSON values do only partially represent the Candid type
  • JSON value for a blob is hex string, should we use hex (simplicity) or base64 (compact)?
  • JSON value for opt differs based on where it's used, makes it more straightforward for consuming services but less consistent for edge cases like opt opt null.

sea-snake avatar Sep 09 '23 12:09 sea-snake

Example JS implementation compatible with autogenerated interfaceFactory that's used in @dfinity/candid: https://github.com/slide-computer/candid-json

sea-snake avatar Sep 10 '23 15:09 sea-snake

Thanks a lot for the contribution, @sea-snake! I would make it clear that it is a one-way transformation, as it is a lossy, if no candid types are given.

However, with the typings, one should be able to go back and forth, right? Would it make sense to write down the transformation algorithm?

@benjizhai: Is this the right repository to create a PR in? This standard is about general data transformation and does not fit nicely in one of the existing categories (I think). Maybe SDK/dev-tooling related?

frederikrothenberger avatar Sep 12 '23 07:09 frederikrothenberger

@frederikrothenberger It's indeed one way but it retains all the structure information needed to go both ways when you have the Candid IDL, as seen in the JS implementation above.

sea-snake avatar Sep 12 '23 09:09 sea-snake