Skip to main content
Use this page when an ABI works locally for analyze or codegen, but explorer reflection still fails or returns incomplete results.

Why Explorer Compatibility Matters

Explorer-side reflection uses the published ABI plus the configured root types to decide how to decode instruction, account, and event bytes. The reflector APIs used by explorer tooling expect:
  • instruction-root for instruction payloads
  • account-root for account data
  • events for emitted event payloads
If those root types are missing, local authoring may still feel fine while explorer decoding fails later.

Required Metadata

Set abi.options.program-metadata.root-types on the published ABI.
options:
  program-metadata:
    root-types:
      instruction-root: "CounterInstruction"
      account-root: "CounterAccount"
      errors: "CounterError"
      events: "CounterEvent"

What Each Root Type Does

Root typeWhat explorer uses it forWhat happens if it is missing
instruction-rootDecode transaction instruction bytesInstruction reflection fails
account-rootDecode account data viewsAccount reflection fails
eventsDecode emitted eventsEvent reflection fails

Prefer A Single Discriminated Instruction Root

Explorer instruction reflection works best when the ABI exposes one discriminated instruction envelope such as CounterInstruction, instead of only a set of unrelated per-instruction structs. That root type should:
  • include a tag or discriminator field
  • point the payload enum at the correct tag field
  • contain every published instruction variant

Minimal Canonical Example

abi:
  package: thru.example.counter
  name: "Counter Program"
  abi-version: 1
  package-version: 1.0.0
  description: Minimal explorer-compatible counter ABI
  imports: []
  options:
    program-metadata:
      root-types:
        instruction-root: "CounterInstruction"
        account-root: "CounterAccount"
        errors: "CounterError"
        events: "CounterEvent"

types:
  - name: InitializeArgs
    kind:
      struct:
        packed: true
        fields:
          - name: seed
            field-type:
              primitive: u64

  - name: IncrementArgs
    kind:
      struct:
        packed: true
        fields:
          - name: amount
            field-type:
              primitive: u64

  - name: CounterInstruction
    kind:
      struct:
        packed: true
        fields:
          - name: tag
            field-type:
              primitive: u8
          - name: payload
            field-type:
              enum:
                packed: true
                tag-ref:
                  field-ref:
                    path:
                      - tag
                variants:
                  - name: initialize
                    tag-value: 0
                    variant-type:
                      type-ref:
                        name: InitializeArgs
                  - name: increment
                    tag-value: 1
                    variant-type:
                      type-ref:
                        name: IncrementArgs

  - name: CounterAccount
    kind:
      struct:
        packed: true
        fields:
          - name: value
            field-type:
              primitive: u64

  - name: CounterEvent
    kind:
      struct:
        packed: true
        fields:
          - name: value
            field-type:
              primitive: u64

  - name: CounterError
    kind:
      enum:
        packed: true
        variants:
          - name: overflow
            tag-value: 0

Publishing Checklist

  1. add program-metadata.root-types
  2. make the instruction root a single discriminated envelope
  3. validate locally with Validation and roundtrip testing
  4. publish the ABI with Publishing and Iteration
  5. inspect the published artifact with Explorer MCP if explorer reflection still looks wrong

Open Next