|
| 1 | +# light-instruction-decoder |
| 2 | + |
| 3 | +Solana instruction decoding library for testing and transaction logging. Decodes raw instruction bytes into human-readable fields, account names, and instruction names. |
| 4 | + |
| 5 | +Supports Anchor programs (8-byte discriminators), native programs (1-byte, 4-byte), and ships with built-in decoders for System Program, SPL Token, Token 2022, Compute Budget, and Light Protocol programs. |
| 6 | + |
| 7 | +## Usage |
| 8 | + |
| 9 | +### Anchor programs |
| 10 | + |
| 11 | +Annotate your program module with `#[instruction_decoder]`: |
| 12 | + |
| 13 | +```rust |
| 14 | +use anchor_lang::prelude::*; |
| 15 | +use light_instruction_decoder_derive::instruction_decoder; |
| 16 | + |
| 17 | +declare_id!("Counter111111111111111111111111111111111111"); |
| 18 | + |
| 19 | +#[instruction_decoder] |
| 20 | +#[program] |
| 21 | +pub mod counter { |
| 22 | + use super::*; |
| 23 | + |
| 24 | + pub fn initialize(ctx: Context<Initialize>) -> Result<()> { /* ... */ } |
| 25 | + pub fn set(ctx: Context<Set>, value: u64) -> Result<()> { /* ... */ } |
| 26 | +} |
| 27 | +``` |
| 28 | + |
| 29 | +This generates a `CounterInstructionDecoder` that automatically extracts instruction names, account names from `Accounts` structs, and parameter types. |
| 30 | + |
| 31 | +### Native programs |
| 32 | + |
| 33 | +Use the derive macro on an enum: |
| 34 | + |
| 35 | +```rust |
| 36 | +use light_instruction_decoder_derive::InstructionDecoder; |
| 37 | + |
| 38 | +#[derive(InstructionDecoder)] |
| 39 | +#[instruction_decoder( |
| 40 | + program_id = "TokenkegQfeZyiNwAJbPVwwQQfKP5nS6Unj84UMP", |
| 41 | + discriminator_size = 1 |
| 42 | +)] |
| 43 | +pub enum TokenInstruction { |
| 44 | + #[instruction_decoder(account_names = ["mint", "account", "owner"])] |
| 45 | + MintTo { amount: u64 }, |
| 46 | + |
| 47 | + #[instruction_decoder(account_names = ["source", "destination", "owner"])] |
| 48 | + Transfer { amount: u64 }, |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +### Decoding transactions |
| 53 | + |
| 54 | +```rust |
| 55 | +use light_instruction_decoder::{DecoderRegistry, EnhancedLoggingConfig}; |
| 56 | + |
| 57 | +let config = EnhancedLoggingConfig::default(); |
| 58 | +let registry = config.decoder_registry(); |
| 59 | + |
| 60 | +if let Some((decoded, decoder)) = registry.decode(&program_id, &data, &accounts) { |
| 61 | + println!("{}: {}", decoder.program_name(), decoded.name); |
| 62 | + for field in &decoded.fields { |
| 63 | + println!(" {}: {}", field.name, field.value); |
| 64 | + } |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +## Development |
| 69 | + |
| 70 | +Requires [just](https://github.com/casey/just) and Solana CLI. |
| 71 | + |
| 72 | +```sh |
| 73 | +just build # Build all crates |
| 74 | +just test # Build SBF program + run all tests |
| 75 | +just lint # Check formatting (nightly) + clippy |
| 76 | +just format # Apply nightly formatting |
| 77 | +``` |
| 78 | + |
| 79 | +## License |
| 80 | + |
| 81 | +Apache-2.0 |
0 commit comments