Skip to content

IDL generation paths diverge: make idl drops #[account_type] that spel generate-idl picks up #141

Description

@vpavlin

Summary

SPEL has two ways to produce an IDL, and they disagree about `#[account_type]`:

Path How it's invoked Picks up `#[account_type]` markers?
CLI subcommand `spel generate-idl methods/guest/src/bin/prog.rs` (→ `spel_framework_core::idl_gen::generate_idl_from_file`) ✅ yes, via `collect_account_types(&file.items)`
Proc macro `spel_framework::generate_idl!("…/prog.rs")` inside `examples/src/bin/generate_idl.rs`, invoked by `make idl` (→ `spel_framework_macros::expand_generate_idl` / `generate_idl_json`) ❌ no

The scaffold's `Makefile` wires `make idl` to the proc-macro path. So a user who follows the tutorial, writes `#[account_type] pub struct CounterState { … }` in the guest file, and runs `make idl`, gets an IDL with `"accounts": []`. Then `spel inspect --type CounterState` silently can't find the type. Nothing in the output tells them why.

The CLI path produces the correct IDL (I confirmed this during the PR #138 tutorial walk):

```bash
spel generate-idl methods/guest/src/bin/my_counter.rs | jq .accounts

[ { "name": "CounterState", "type": { "kind": "struct", "fields": [ … ] } } ]

```

Why this happens

`spel_framework_core/src/idl_gen.rs` (CLI path) calls `collect_account_types(&file.items)` after parsing the program source. `spel_framework_macros/src/lib.rs::generate_idl_json` (proc-macro path) walks `instructions` but never iterates `file.items` looking for `#[account_type]` markers — so the top-level structs/enums annotated with it are silently dropped when emitting `PROGRAM_IDL_JSON`.

Proposed fix

Two options:

  1. Unify on one path. Have `generate_idl_fn` / `generate_idl_json` in `spel-framework-macros` delegate to the same `collect_account_types` logic (or to `idl_gen::generate_idl_from_str` directly). Both produce an `SpelIdl`; the proc-macro path just needs to serialize it.

  2. Port the collection. Copy the `collect_account_types` logic into `generate_idl_json` so it builds the `accounts`/`types` entries from the file's top-level items. Less invasive but duplicates code.

Option 1 is the clean fix.

Workaround (until fixed)

Replace `make idl` with `spel generate-idl methods/guest/src/bin/.rs > -idl.json`. The tutorial in PR #138 tells users to do this and explains why.

Impact

`spel inspect --type …` is the primary way to read account data off-chain, and it's prominently advertised in the README ("inspect subcommand to extract ProgramId from binaries and decode account data"). Any user who defines state via `#[account_type]` and generates the IDL via `make idl` will hit this.

Found during the tutorial walk that produced #138.

cc @fryorcraken

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions