Skip to content

Instantly share code, notes, and snippets.

@thlorenz
Created August 28, 2025 08:52
Show Gist options
  • Save thlorenz/811a613eb63b646b6c135d6d2b59b62f to your computer and use it in GitHub Desktop.
Save thlorenz/811a613eb63b646b6c135d6d2b59b62f to your computer and use it in GitHub Desktop.

Revisions

  1. thlorenz created this gist Aug 28, 2025.
    10 changes: 10 additions & 0 deletions Cargo.toml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    [package]
    name = "feepayer"
    version = "0.1.0"
    edition = "2024"

    [dependencies]
    solana-instruction = "3.0.0"
    solana-pubkey = "3.0.0"
    solana-sanitize = "3.0.1"
    solana-transaction = { version = "3.0.1", features = ["blake3"] }
    62 changes: 62 additions & 0 deletions main.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    use std::collections::HashSet;

    use solana_sanitize::Sanitize;

    use solana_instruction::{AccountMeta, Instruction};
    use solana_pubkey::Pubkey;
    use solana_transaction::{sanitized::SanitizedTransaction, Transaction};

    fn sanitize_ixs(ixs: &[Instruction], payer: Option<Pubkey>, label: &str) -> Transaction {
    let tx = Transaction::new_with_payer(ixs, payer.as_ref());
    let res = tx.sanitize();
    eprintln!("{label:18}: {res:?}");
    tx
    }

    fn main() {
    let program = Pubkey::default();
    let payer = Pubkey::new_unique();

    // No accounts
    let ix = Instruction::new_with_bytes(program, &[], vec![]);
    sanitize_ixs(&[ix], None, "Empty Accounts");

    // Readonly Payer
    let payer_meta = AccountMeta::new_readonly(payer, false);
    let ix = Instruction::new_with_bytes(program, &[], vec![payer_meta]);
    sanitize_ixs(&[ix], None, "Readonly");

    // Readonly signing payer
    let payer_meta = AccountMeta::new_readonly(payer, true);
    let ix = Instruction::new_with_bytes(program, &[], vec![payer_meta]);
    sanitize_ixs(&[ix], None, "Readonly signing");

    // Writable Payer
    let payer_meta = AccountMeta::new(payer, false);
    let ix = Instruction::new_with_bytes(program, &[], vec![payer_meta]);
    sanitize_ixs(&[ix], None, "Writable");

    // Writable signing payer
    let payer_meta = AccountMeta::new(payer, true);
    let ix = Instruction::new_with_bytes(program, &[], vec![payer_meta]);
    let tx = sanitize_ixs(&[ix], None, "Writable signing");
    let sanitized = SanitizedTransaction::try_from_legacy_transaction(tx.clone(), &HashSet::new());
    eprintln!(" : {sanitized:#?}");

    // Explicit payer
    let ix = Instruction::new_with_bytes(program, &[], vec![]);
    let tx = sanitize_ixs(&[ix], Some(payer), "Explicit payer");
    let sanitized = SanitizedTransaction::try_from_legacy_transaction(tx.clone(), &HashSet::new());
    eprintln!(" : {sanitized:#?}");

    // Explicit payer used as readonly in ix
    let payer_meta = AccountMeta::new_readonly(payer, false);
    let ix = Instruction::new_with_bytes(program, &[], vec![payer_meta]);
    let tx = sanitize_ixs(
    &[ix],
    Some(payer),
    "Explicit payer included as readonly not signing",
    );
    let sanitized = SanitizedTransaction::try_from_legacy_transaction(tx.clone(), &HashSet::new());
    eprintln!(" : {sanitized:#?}");
    }