feat: expose identify/parse helpers on generated program plugins#143
Conversation
Generated program plugins now re-expose the existing per-program identifier and parser helpers as plugin fields. When a program has accounts with discriminators, the plugin gains an `identifyAccount` field bound to the generated `identify*Account` function. When any instruction (respecting `renderParentInstructions`) carries a discriminator, the plugin gains `identifyInstruction` and `parseInstruction` fields bound to the generated `identify*Instruction` and `parse*Instruction` functions. Emission mirrors the conditions under which those helper functions themselves get rendered, so the plugin shape stays consistent with the rest of the program page. Tests cover the discriminator-present, sub-instruction-only, no-discriminator, and `renderParentInstructions: true` paths at both the fragment level and the full program-page level. E2E fixtures regenerated to reflect the new plugin shape.
Add three ava tests in the dummy e2e fixture that exercise the new plugin shape against real generator-built instructions. The first two assert that identifyDummyInstruction and parseDummyInstruction round-trip the bytes encoded by getInstruction3Instruction and getInstruction10Instruction back to their enum variants, giving us coverage that the encoder and identifier agree on the wire format. The third applies dummyProgram() to a stub client and verifies its identifyInstruction/parseInstruction fields behave identically to the standalone helpers. Also fix two prettier-flagged line-break issues in programPlugin.ts that were masked in the previous lint run by eslint's short-circuit. The e2e workspace now resolves @solana/kit at 6.8.0 (versus 6.1.0 before the lockfile-driven reinstall), which surfaces extendClient typings and lets the prettier check run cleanly.
🦋 Changeset detectedLatest commit: f386fab The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
trevor-cortex
left a comment
There was a problem hiding this comment.
Summary
Re-exposes identifyAccount, identifyInstruction, and parseInstruction on generated program plugins so consumers can call them off the client (e.g. client.myProgram.parseInstruction(ix)) without importing the per-program helpers separately. Useful for indexers and anything that switches on instruction kind.
The plugin type and the plugin function are both updated symmetrically, and emission is gated by the same conditions that drive the underlying helper generation:
identifyAccountis emitted iff at least one account has a discriminator (mirrorsgetProgramAccountsIdentifierFunctionFragment).identifyInstruction/parseInstructionare emitted iff at least one instruction (after the samegetAllInstructionsWithSubs({ leavesOnly: !renderParentInstructions })walk used bygetProgramInstructionsFragment) has a discriminator.
Threading renderParentInstructions into getProgramPluginFragment/getProgramPluginTypeFragment/getProgramPluginFunctionFragment is required for that second condition to stay in sync — programPage.ts already had it in scope, so the plumbing is local.
Things to watch
- Condition parity:
hasAccountIdentifierandhasInstructionIdentifierduplicate the predicates fromprogramAccounts.ts/programInstructions.ts. They match today; if those upstream conditions ever change (e.g. additional gating beyonddiscriminators.length > 0), these will need to change in lockstep. A short comment is already present onhasInstructionIdentifier; worth keeping in mind for future edits. - Field ordering: the new keys are appended after
pdasin both the type and the function. Cosmetic only, but placingidentifyAccountnext toaccountsandidentifyInstruction/parseInstructionnext toinstructionswould read more naturally. Not blocking — current placement is consistent across type + function and matches the regenerated e2e fixtures.
Notes for subsequent reviewers
- E2E fixtures across
dummy,system,token,associatedToken, andwenTransferGuardhave been regenerated and look consistent with the new emission rules (e.g.associatedTokenonly getsidentifyInstruction/parseInstructionbecause it has no accounts;tokengets all three;dummygets only the instruction pair). - The new
dummyAVA test exercises the plugin via a stub{} as DummyPluginRequirementscast — fine here becauseidentifyInstruction/parseInstructionare bare references that don't read from the client, but worth remembering if either helper ever becomes client-aware. - Tests cover the four interesting cases: discriminators present on both sides, sub-instruction-only discriminators, no discriminators (negative case), and
renderParentInstructions: trueflipping a parent-only discriminator into emission. Good coverage. - Changeset is
minorand the description is accurate.
Summary
identifyAccount,identifyInstruction, andparseInstructionon the generated program plugin, so consumers can callclient.myProgram.identifyInstruction(ix)without importing the per-function helpers.renderParentInstructions).dummy) round-trip coverage; e2e fixtures regenerated.Test Plan
pnpm test:unitcd test/e2e/dummy && pnpm test