feat: Add SPL Token batch instruction decoding#903
feat: Add SPL Token batch instruction decoding#903askov wants to merge 6 commits intosolana-foundation:masterfrom
Conversation
|
@askov is attempting to deploy a commit to the Solana Foundation Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR introduces a hand-rolled parser and renderer for SPL Token / Token-2022 Key changes:
Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["InstructionsSection\n(InstructionCard dispatcher)"] -->|isTokenBatchInstruction| B["TokenBatchCard"]
B --> C["parseBatchInstruction\n(batch-parser.ts)"]
C -->|reads wire format\nu8 num_accounts · u8 data_len · payload| D["ParsedBatchSubInstruction[]"]
D --> E["SubInstructionRow × N"]
E --> F{"decodeSubInstructionParams\n(decode-sub-instruction.ts)"}
F -->|known base instruction| G["DecodedContent\n(named fields + labeled accounts)"]
F -->|Unknown / extension| H["RawContent\n(raw hex + Account N labels)"]
C -->|parse error| I["Error message\n(batch-error)"]
C -->|empty batch| J["No sub-instructions found\n(batch-empty)"]
Reviews (2): Last reviewed commit: "fix: Update SPL Token sub-instruction to..." | Re-trigger Greptile |
…ders and improve error handling
|
@greptile-apps review please |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| throw new Error(`Truncated data: expected num_accounts and data_len at offset ${offset}`); | ||
| } | ||
| const numAccounts = readU8(data, offset); | ||
| const dataLen = readU8(data, offset + 1); |
There was a problem hiding this comment.
Question: should we add here a comment noting this is intentional and matches the wire format spec?
| offset += a.length; | ||
| } | ||
| return result; | ||
| } |
There was a problem hiding this comment.
#801 introduces the same functionality to work with bytes here: https://github.com/solana-foundation/explorer/pull/801/changes#diff-4cc2aaeb6c175b24395ee3778bb801815aaf9d2935d6249e9c8d0c77901545d2R131-R154
Let's move this into the shared helper
|
Current PR adds support for Batch instructions on the TX page, but Inspector has no conditions to render it properly. @Woody4618 do you think we need to support it here, or a separate PR is good? |
| accounts: AccountEntry[], | ||
| ): DecodedParams | undefined { | ||
| switch (typeName) { | ||
| case 'Transfer': { |
There was a problem hiding this comment.
I'd suggest to "mimic" structure that does exist for the client already. Check the sample: https://github.com/hoodieshq/explorer/blob/4500073c57aa0a04a45f37f3dfda39cd1a6f1aa0/app/components/inspector/instruction-parsers/spl-token.parser.ts#L3-L11
The client provides separate functions for every case. I think it is beneficial to move the implementation for each type into a separate helper.
| }; | ||
| } | ||
|
|
||
| case 'Approve': { |
There was a problem hiding this comment.
I can not see tests for all the decodeByType cases. Might lead to potential degradation.
| transferChecked: roles('Source', 'Mint', 'Destination', 'Owner/Delegate'), | ||
| }; | ||
|
|
||
| // Lazily initialized decoders — created once on first use. |
There was a problem hiding this comment.
nit: looks like this is not 'lazily' but 'eagerly', right?
| 39: 'MetadataPointerExtension', | ||
| 40: 'GroupPointerExtension', | ||
| 41: 'GroupMemberPointerExtension', | ||
| 43: 'ScaledUiAmountExtension', |
There was a problem hiding this comment.
Let's add a comment on why the 42nd is not included.
| // Maps SPL Token sub-instruction discriminators to human-readable names. | ||
| // Base instructions (0–24, 38, 45): | ||
| // https://github.com/solana-program/token/blob/065786e/pinocchio/interface/src/instruction.rs#L9-L551 | ||
| // Token-2022 extension instructions (25–44): |
There was a problem hiding this comment.
Let's exclude 38 here to make the range match to the Base instructions
| const typeName = (discriminator !== undefined && typeNameByDiscriminator[discriminator]) || 'Unknown'; | ||
|
|
||
| if (typeName === 'Unknown') { | ||
| Logger.warn('[token-batch] Unknown sub-instruction discriminator', { discriminator, index: subIndex }); |
There was a problem hiding this comment.
WDYT we move Logger usage out of the /lib helper to make it not rely on logger?





Description
Parse and render the Token/Token-2022
Batchinstruction (0xff), which packs multiple sub-instructions into a single instruction's data. No published SDK exposes a decoder for this wire format, so the parser is hand-rolled against the on-chain layout.Type of change
Screenshots
Testing
Related Issues
Closes HOO-380
Checklist
build:infoscript to update build information