paritytech/capi

use custom metadata format based on scale codecs

tjjfvi opened this issue · 1 comments

Currently, the metadata looks like:

{
  tys: [
    { id: 0, type: "Primitive", kind: "u8" },
    {
      id: 1,
      type: "SizedArray",
      typeParam: { id: 0, type: "Primitive", kind: "u8" },
      len: 32,
   },
   ...
  ],
  pallets: [
    {
      i: 0,
      name: "System",
      storage: {
        prefix: "System",
        entries: [
          {
            name: "Account",
            type: "Map",
            key: { id: 1, type: "SizedArray", ... },
            ...
          },
          ...
        ],
      },
    },
    ...
  ],
}

Instead, let's transform it into:

{
  tys: [
    $.u8,
    $.sizedArray($.u8, 32),
    ...
  ],
  pallets: {
    System: {
      id: 0,
      name: "System",
      storagePrefix: "System", // todo: is this always the same as `name`?
      storage: {
        Account: {
          name: "Account",
          key: $.sizedArray($.u8, 32),
          ...
        },
      },
      ...
    },
  }
}

Right now, to decode a storage value, you have to do this:

const deriveCodec = DeriveCodec(metadata.tys);
const pallet = metadata.pallets.find(p => p.name === palletName)
const storage = pallet.storage.entries.find(s => s.name === storageName)
const $value = deriveCodec(storage.value)
$value.decode(...)

With the new metadata format, it's as simple as:

const pallet = metadata.pallets[palletName]
const storage = pallet.storage[storageName]
storage.value.decode(...)

This change will make scale codecs our universal language for types, and will greatly ease the process of supporting new versions of the frame metadata.

Will also simplify/unblock #412

Should account for #551