gmsol/utils/
instruction.rs

1use anchor_client::{anchor_lang::AnchorSerialize, solana_sdk::instruction::Instruction};
2use base64::{engine::general_purpose::STANDARD, Engine};
3use solana_sdk::pubkey::Pubkey;
4use spl_governance::state::proposal_transaction::InstructionData;
5
6/// Instruction serialziation format.
7#[derive(Default, Clone, Copy)]
8#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
9pub enum InstructionSerialization {
10    /// SPL-Governance format.
11    #[default]
12    Gov,
13    /// Base58 (Squads).
14    Base58,
15    /// Base64.
16    Base64,
17}
18
19/// Serialize an instruction.
20pub fn serialize_instruction(
21    ix: &Instruction,
22    format: InstructionSerialization,
23    payer: Option<&Pubkey>,
24) -> crate::Result<String> {
25    use solana_sdk::message::legacy::Message;
26
27    let message = match format {
28        InstructionSerialization::Gov => {
29            let data = InstructionData::from(ix.clone()).try_to_vec()?;
30            STANDARD.encode(data)
31        }
32        InstructionSerialization::Base58 | InstructionSerialization::Base64 => {
33            let message = Message::new(&[ix.clone()], payer);
34            match format {
35                InstructionSerialization::Base58 => bs58::encode(message.serialize()).into_string(),
36                InstructionSerialization::Base64 => STANDARD.encode(message.serialize()),
37                _ => {
38                    unreachable!()
39                }
40            }
41        }
42    };
43
44    Ok(message)
45}