### Order and Bundle Solana Instructions - Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt Processes transaction data to extract and organize outer and inner instructions using the `order_instructions` function. It identifies relevant programs, bundles instructions into an `InstructionBundle`, and routes them for parsing. ```rust use blockbuster::instruction::{order_instructions, InstructionBundle}; use plerkle_serialization::TransactionInfo; use std::collections::HashSet; // Define programs you want to track let mut tracked_programs = HashSet::new(); tracked_programs.insert(mpl_bubblegum::id().as_ref()); tracked_programs.insert(spl_account_compression::id().as_ref()); tracked_programs.insert(mpl_token_metadata::id().as_ref()); // Transaction received from geyser plugin let transaction_info: TransactionInfo = get_transaction_from_geyser(); // Order instructions for processing let ordered_instructions = order_instructions(tracked_programs, &transaction_info); // Process each instruction bundle for ((program_id, instruction), inner_instructions) in ordered_instructions { let account_keys = transaction_info.account_keys() .unwrap() .iter() .collect::>(); let bundle = InstructionBundle { txn_id: transaction_info.signature().unwrap(), program: program_id, instruction: Some(instruction), inner_ix: inner_instructions, keys: &account_keys, slot: transaction_info.slot(), }; // Route to appropriate parser based on program_id if program_id.0 == mpl_bubblegum::id().to_bytes() { let parser = BubblegumParser; let result = parser.handle_instruction(&bundle).unwrap(); // Process result... } } ``` -------------------------------- ### Parse SPL Account Compression Instructions with Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt Processes SPL Account Compression program instructions for managing compressed merkle trees using AccountCompressionParser. It handles instructions like InitTree, ReplaceLeaf, Append, and TransferAuthority, along with tree update details. Requires the 'blockbuster' and 'spl-account-compression' crates. ```rust use blockbuster::{ program_handler::ProgramParser, programs::{ account_compression::{AccountCompressionParser, Instruction}, ProgramParseResult, }, instruction::InstructionBundle, }; use spl_account_compression::id as compression_program_id; let parser = AccountCompressionParser; let instruction_bundle = InstructionBundle { txn_id: "txn_123", program: Pubkey::new(&compression_program_id().to_bytes()), instruction: Some(compiled_ix), inner_ix: Some(inner_ixs), keys: &account_keys, slot: 987654, }; match parser.handle_instruction(&instruction_bundle) { Ok(result) => { if let ProgramParseResult::AccountCompression(compression_ix) = result.result_type() { match &compression_ix.instruction { Instruction::InitTree { max_depth, max_buffer_size } => { println!("Initializing tree: depth={}, buffer={}", max_depth, max_buffer_size); }, Instruction::ReplaceLeaf { root, previous_leaf, new_leaf, index } => { println!("Replacing leaf at index {}", index); println!("Root: {:?}", root); }, Instruction::Append { leaf } => { println!("Appending leaf: {:?}", leaf); }, Instruction::TransferAuthority { new_authority } => { println!("Transferring authority to: {}", new_authority); }, _ => {} } if let Some(tree_update) = &compression_ix.tree_update { println!("Changelog ID: {:?}", tree_update.id); println!("Sequence: {}", tree_update.seq); } } }, Err(e) => eprintln!("Compression parse error: {:?}", e), } ``` -------------------------------- ### Parse Bubblegum NFT Instructions with Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt Parses Metaplex Bubblegum program instructions for compressed NFTs using the BubblegumParser. It extracts details like NFT name, symbol, URI, and tree/leaf update information. Requires the 'blockbuster', 'plerkle-serialization', and 'mpl-bubblegum' crates. ```rust use blockbuster::{ program_handler::ProgramParser, programs::{ bubblegum::{BubblegumParser, Payload}, ProgramParseResult, }, instruction::InstructionBundle, }; use plerkle_serialization::{Pubkey, CompiledInstruction}; use mpl_bubblegum::InstructionName; // Create parser instance let parser = BubblegumParser; // Build instruction bundle from transaction data let instruction_bundle = InstructionBundle { txn_id: "transaction_signature_here", program: Pubkey::new(&mpl_bubblegum::id().to_bytes()), instruction: Some(compiled_instruction), inner_ix: Some(inner_instructions), keys: &account_keys, slot: 12345678, }; // Parse the instruction match parser.handle_instruction(&instruction_bundle) { Ok(result) => { if let ProgramParseResult::Bubblegum(bubblegum_ix) = result.result_type() { // Check instruction type match bubblegum_ix.instruction { InstructionName::MintV1 => { if let Some(Payload::MintV1 { args }) = &bubblegum_ix.payload { println!("NFT Name: {}", args.name); println!("Symbol: {}", args.symbol); println!("URI: {}", args.uri); } }, InstructionName::Transfer => { println!("Transfer detected"); }, InstructionName::VerifyCreator => { if let Some(Payload::CreatorVerification { creator, verify }) = &bubblegum_ix.payload { println!("Creator: {}, Verified: {}", creator, verify); } }, _ => {} } // Access tree and leaf updates if let Some(tree_update) = &bubblegum_ix.tree_update { println!("Tree ID: {:?}", tree_update.id); println!("Tree path length: {}", tree_update.path.len()); } if let Some(leaf_update) = &bubblegum_ix.leaf_update { println!("Leaf schema version: {:?}", leaf_update.version); } } }, Err(e) => eprintln!("Parse error: {:?}", e), } ``` -------------------------------- ### Implement Custom Program Parsers with ProgramParser Trait in Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt Demonstrates how to implement the ProgramParser trait to create custom parsers for Solana programs. This involves defining a custom result type and implementing methods to handle program instructions and account updates. It's crucial for integrating new programs into the BlockBuster framework for data indexing and analysis. ```rust use blockbuster::{ program_handler::{ProgramParser, ParseResult, NotUsed}, error::BlockbusterError, instruction::InstructionBundle, programs::ProgramParseResult, }; use plerkle_serialization::AccountInfo; use solana_sdk::pubkey::Pubkey; // Custom result type for your parser pub struct MyProgramResult { pub instruction_type: String, pub data: Vec, } impl ParseResult for MyProgramResult { fn result_type(&self) -> ProgramParseResult { ProgramParseResult::Unknown } fn result(&self) -> &Self { self } } // Implement the parser pub struct MyProgramParser; impl ProgramParser for MyProgramParser { fn key(&self) -> Pubkey { // Return your program ID Pubkey::new_from_array([1; 32]) } fn key_match(&self, key: &Pubkey) -> bool { key == &self.key() } fn handles_instructions(&self) -> bool { true } fn handles_account_updates(&self) -> bool { false } fn handle_instruction( &self, bundle: &InstructionBundle, ) -> Result, BlockbusterError> { let instruction = bundle.instruction .ok_or(BlockbusterError::InstructionParsingError)?; let data = instruction.data() .ok_or(BlockbusterError::DeserializationError)? .iter() .collect::>(); Ok(Box::new(MyProgramResult { instruction_type: "CustomInstruction".to_string(), data, })) } fn handle_account( &self, _account_info: &AccountInfo, ) -> Result, BlockbusterError> { Ok(Box::new(NotUsed::new())) } } ``` -------------------------------- ### BlockbusterError Handling for Instruction Parsing - Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt Demonstrates comprehensive error handling for parsing failures using the `BlockbusterError` enum. It covers various specific errors like `InstructionParsingError`, `DeserializationError`, and `MissingBubblegumEventData`. ```rust use blockbuster::{ error::BlockbusterError, program_handler::ProgramParser, programs::bubblegum::BubblegumParser, }; let parser = BubblegumParser; match parser.handle_instruction(&bundle) { Ok(result) => { println!("Successfully parsed instruction"); // Process result... }, Err(BlockbusterError::InstructionParsingError) => { eprintln!("Failed to parse instruction data"); }, Err(BlockbusterError::DeserializationError) => { eprintln!("Failed to deserialize binary data"); }, Err(BlockbusterError::MissingBubblegumEventData) => { eprintln!("Required Bubblegum event data not found in noop instruction"); }, Err(BlockbusterError::MissingAccountCompressionEventData) => { eprintln!("Required Account Compression event data not found"); }, Err(BlockbusterError::InvalidDataLength) => { eprintln!("Account data length does not match expected size"); }, Err(BlockbusterError::UnknownAccountDiscriminator) => { eprintln!("Unknown anchor account discriminator"); }, Err(BlockbusterError::UninitializedAccount) => { eprintln!("Account has not been initialized"); }, Err(BlockbusterError::CustomDeserializationError(msg)) => { eprintln!("Custom deserialization error: {}", msg); }, Err(e) => { eprintln!("Other error: {:?}", e); } } ``` -------------------------------- ### Parse Metaplex Token Metadata Accounts with Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt This snippet demonstrates how to use the TokenMetadataParser to deserialize Metaplex Token Metadata account data. It handles various account types like MetadataV1, MasterEditionV2, and EditionV1, extracting relevant information such as NFT name, symbol, URI, mint, and edition details. Dependencies include the blockbuster and plerkle_serialization crates. ```rust use blockbuster::{ program_handler::ProgramParser, programs::{ token_metadata::{TokenMetadataParser, TokenMetadataAccountData}, ProgramParseResult, }, }; use plerkle_serialization::AccountInfo; use mpl_token_metadata::state::Key; let parser = TokenMetadataParser; // Parse account data received from geyser plugin match parser.handle_account(&account_info) { Ok(result) => { if let ProgramParseResult::TokenMetadata(metadata_state) = result.result_type() { match metadata_state.key { Key::MetadataV1 => { if let TokenMetadataAccountData::MetadataV1(metadata) = &metadata_state.data { println!("NFT Name: {}", metadata.data.name); println!("Symbol: {}", metadata.data.symbol); println!("URI: {}", metadata.data.uri); println!("Mint: {}", metadata.mint); println!("Update Authority: {}", metadata.update_authority); println!("Seller Fee Basis Points: {}", metadata.data.seller_fee_basis_points); if let Some(creators) = &metadata.data.creators { for creator in creators { println!("Creator: {}, Share: {}%, Verified: {}", creator.address, creator.share, creator.verified); } } } }, Key::MasterEditionV2 => { if let TokenMetadataAccountData::MasterEditionV2(edition) = &metadata_state.data { println!("Max Supply: {:?}", edition.max_supply); println!("Supply: {}", edition.supply); } }, Key::EditionV1 => { if let TokenMetadataAccountData::EditionV1(edition) = &metadata_state.data { println!("Parent: {}", edition.parent); println!("Edition: {}", edition.edition); } }, _ => println!("Other metadata account type"), } } }, Err(e) => eprintln!("Metadata parse error: {:?}", e), } ``` -------------------------------- ### Parse SPL Token Accounts with Rust Source: https://context7.com/honeycomb-protocol/blockbuster/llms.txt This code snippet shows how to use the TokenAccountParser to process SPL Token program account updates. It can deserialize both token accounts and mint accounts, extracting details like mint, owner, amount, supply, and decimals. This functionality is crucial for interacting with tokens on the Solana blockchain. Dependencies include the blockbuster and plerkle_serialization crates. ```rust use blockbuster::{ program_handler::ProgramParser, programs::{ token_account::{TokenAccountParser, TokenProgramAccount}, ProgramParseResult, }, }; use plerkle_serialization::AccountInfo; let parser = TokenAccountParser; match parser.handle_account(&account_info) { Ok(result) => { if let ProgramParseResult::TokenProgramAccount(token_account) = result.result_type() { match token_account { TokenProgramAccount::TokenAccount(account) => { println!("Mint: {}", account.mint); println!("Owner: {}", account.owner); println!("Amount: {}", account.amount); println!("Delegate: {:?}", account.delegate); println!("State: {:?}", account.state); println!("Is Native: {:?}", account.is_native); println!("Delegated Amount: {}", account.delegated_amount); println!("Close Authority: {:?}", account.close_authority); }, TokenProgramAccount::Mint(mint) => { println!("Mint Authority: {:?}", mint.mint_authority); println!("Supply: {}", mint.supply); println!("Decimals: {}", mint.decimals); println!("Is Initialized: {}", mint.is_initialized); println!("Freeze Authority: {:?}", mint.freeze_authority); }, TokenProgramAccount::EmptyAccount => { println!("Empty token account"); } } } }, Err(e) => eprintln!("Token account parse error: {:?}", e), } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.