### Generate Solores Examples Source: https://github.com/igneous-labs/solores/blob/master/examples/README.md Command to generate example crates for the Solores project. This command is executed from the workspace root and utilizes Cargo to run tests with the 'test_gen_examples' feature enabled, which is crucial for the example generation process. ```shell cd solores && cargo test --features test_gen_examples ``` -------------------------------- ### Shank IDL Example Source: https://github.com/igneous-labs/solores/blob/master/README.md An example of a Shank IDL file defining a token transfer instruction and its arguments. ```json { "name": "my_token", "instructions": [ { "name": "transfer", "accounts": [ { "name": "src", "isMut": true, "isSigner": true }, { "name": "dest", "isMut": true, "isSigner": false } ], "args": [ { "name": "transferArgs", "type": { "defined": "TransferArgs" } } ], "discriminant": { "type": "u8", "value": 0 } } ], "types": [ { "name": "TransferArgs", "type": { "kind": "struct", "fields": [ { "name": "amount", "type": "u64" } ] } } ] } ``` -------------------------------- ### Test Solores Consumer Crates Source: https://github.com/igneous-labs/solores/blob/master/examples/README.md Command to test the consumer crates of the Solores project. This step is performed after the example generation stage and ensures the functionality of the crates that utilize the generated examples. ```shell cargo test ``` -------------------------------- ### Install Solores CLI Source: https://github.com/igneous-labs/solores/blob/master/README.md Command to install the solores command-line interface binary using Cargo, the Rust package manager. ```Shell cargo install solores ``` -------------------------------- ### Client-Side App Usage (Shank) Source: https://github.com/igneous-labs/solores/blob/master/README.md Example of generating and using an instruction for a client-side application using a Solores-generated Rust crate. ```rust use my_token_interface::{TransferKeys, TransferArgs, transfer_ix}; pub fn do_something_with_instruction() -> std::io::Result<()> { ... let transfer_accounts = TransferKeys { src: some_pubkey, dest: another_pubkey, }; let transfer_ix_args = TransferIxArgs { transfer_args: TransferArgs { amount: 1_000 }, }; let ix = transfer_ix(transfer_accounts, transfer_ix_args)?; ... } ``` -------------------------------- ### Keys From Array Usage Source: https://github.com/igneous-labs/solores/blob/master/README.md Example showing how generated `*Keys` structs implement `From<[Pubkey; N]>` for easier account indexing. ```rust use my_token_interface::{TRANSFER_IX_ACCOUNTS_LEN, TransferKeys}; use solana_program::{pubkey::Pubkey, sysvar::instructions::{BorrowedAccountMeta, BorrowedInstruction}}; use std::convert::TryInto; fn index_instruction(ix: BorrowedInstruction) { let metas: [BorrowedAccountMeta<'_>; TRANSFER_IX_ACCOUNTS_LEN] = ix.accounts.try_into().unwrap(); let pubkeys = metas.map(|meta| *meta.pubkey); let transfer_keys: TransferKeys = pubkeys.into(); // Now you can do stuff like `transfer_keys.src` instead of // having to keep track of the various account indices // // ... } ``` -------------------------------- ### On-Chain Program Usage (Shank) Source: https://github.com/igneous-labs/solores/blob/master/README.md Example of using a Solores-generated Rust crate within an on-chain Solana program to invoke a transfer instruction. ```rust use my_token_interface::{TransferAccounts, TransferArgs, TransferIxArgs, transfer_invoke_signed}; use solana_program::{account_info::{AccountInfo, next_account_info}, entrypoint::ProgramResult, program::invoke, pubkey::Pubkey}; pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let account_info_iter = &mut accounts.iter(); let src = next_account_info(account_info_iter)?; let dest = next_account_info(account_info_iter)?; transfer_invoke_signed( TransferAccounts { src, dest }, TransferIxArgs { transfer_args: TransferArgs { amount: 1_000 }, }, &[&[&[0u8]]], ) ``` -------------------------------- ### Drift v2 Program Dependencies and Configuration Source: https://github.com/igneous-labs/solores/blob/master/examples/anchor/drift/README.md Notes on the Drift v2 program's build environment and configuration. It highlights the default program ID used when the IDL lacks explicit definition and the required versions for key Rust crates. ```text Default Program ID: TH1S1SNoTAVAL1DPUBKEYDoNoTUSE11111111111111 Required Dependencies: solana-program = "^1.16" borsh = "^0.10" ``` -------------------------------- ### Accounts From Array Implementation Source: https://github.com/igneous-labs/solores/blob/master/README.md Demonstrates how various `*Accounts` types implement `From<&[AccountInfo; *_IX_ACCOUNTS_LEN]>` for ergonomic unpacking from program account slices. ```rust use my_token_interface::{TRANSFER_IX_ACCOUNTS_LEN, TransferAccounts, TransferArgs, TransferIxArgs, transfer_invoke}; use solana_program::{account_info::{AccountInfo, next_account_info}, entrypoint::ProgramResult, program::invoke, pubkey::Pubkey}; pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let transfer_accounts: &[AccountInfo; TRANSFER_IX_ACCOUNTS_LEN] = accounts[..TRANSFER_IX_ACCOUNTS_LEN].try_into().unwrap(); let accounts: TransferAccounts = transfer_accounts.into(); transfer_invoke( accounts, TransferIxArgs { transfer_args: TransferArgs { amount: 1_000 }, } ) } ``` -------------------------------- ### Drift v2 Program IDL Source Source: https://github.com/igneous-labs/solores/blob/master/examples/anchor/drift/README.md The Interface Definition Language (IDL) for the Drift v2 program is available from the specified GitHub repository. This file defines the program's structure and operations. ```json https://github.com/drift-labs/protocol-v2/blob/master/sdk/src/idl/drift.json ``` -------------------------------- ### Instruction Account Pubkey Verification Source: https://github.com/igneous-labs/solores/blob/master/README.md Provides a function to compare instruction `*Accounts` pubkeys against a `*Keys` struct, returning the first non-matching pair as an error. This function is generated only if the instruction has account inputs. ```rust use my_token_interface::{TransferAccounts, TransferKeys, transfer_verify_account_keys}; use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey, program_error::ProgramError}; pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let accounts: TransferAccounts = ... let expected_keys: TransferKeys = ... // transfer_verify_account_keys() returns the first non-matching pubkeys between accounts and expected_keys if let Err((actual_pubkey, expected_pubkey)) = transfer_verify_account_keys(accounts, expected_keys) { return Err(ProgramError::InvalidAccountData); } } ``` -------------------------------- ### Instruction Account Privilege Verification Source: https://github.com/igneous-labs/solores/blob/master/README.md Generates a function to ensure writable and signer privileges for instruction `*Accounts` structs. It returns an error with the offending account and program error if privileges are not met. This is omitted if no accounts require signer/writable privileges. ```rust use my_token_interface::{TransferAccounts, TransferKeys, transfer_verify_account_privileges}; use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey, program_error::ProgramError}; pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let accounts: TransferAccounts = ... if let Err((offending_acc, program_err)) = transfer_verify_account_privileges(accounts) { solana_program::msg!("Writable/signer privilege escalation for {}: {}", offending_acc.key, program_err); return Err(program_err); } } ``` -------------------------------- ### Instruction Functions with Custom Program ID Source: https://github.com/igneous-labs/solores/blob/master/README.md Provides variants of instruction functions that accept a custom program ID pubkey. These include `*_ix_with_program_id()`, `*_invoke_with_program_id()`, and `*_invoke_signed_with_program_id()`, enabling program invocation at different IDs. ```rust // Example for *_ix_with_program_id() // let instruction = my_instruction_ix_with_program_id( // program_id_pubkey, // accounts_struct, // args_struct // ); // Example for *_invoke_with_program_id() // let result = my_instruction_invoke_with_program_id( // program_id_pubkey, // accounts_struct, // args_struct // ); // Example for *_invoke_signed_with_program_id() // let result = my_instruction_invoke_signed_with_program_id( // program_id_pubkey, // accounts_struct, // args_struct, // signer_seeds // ); ``` -------------------------------- ### Borsh Serde Roundtrip Test (Shank) Source: https://github.com/igneous-labs/solores/blob/master/README.md Demonstrates testing the Borsh serialization and deserialization of a generated `ProgramIx` enum from a Shank IDL. ```rust use borsh::BorshSerialize; use my_token_interface::{MyTokenProgramIx, TransferArgs, TransferIxArgs}; #[test] pub fn test_borsh_serde_roundtrip_program_ix() { let program_ix = MyTokenProgramIx::Transfer( TransferIxArgs { transfer_args: TransferArgs { amount: 1 }, } ); // [0, 1, 0, 0, 0, 0, 0, 0, 0] let serialized = program_ix.try_to_vec().unwrap(); // note that deserialize is an associated function/method // rather than the BorshDeserialize trait impl // i.e. MyTokenProgramIx does NOT impl BorshDeserialize // since it doesn't follow the borsh spec let deserialized = MyTokenProgramIx::deserialize(&serialized).unwrap(); assert_eq!(program_ix, deserialized); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.