gmsol_sdk/utils/
instruction_serialization.rs1use std::borrow::Cow;
2
3use base64::{engine::general_purpose::STANDARD, Engine};
4use solana_sdk::instruction::Instruction;
5use solana_sdk::pubkey::Pubkey;
6
7#[derive(Debug, Default, Clone, Copy)]
9#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
12pub enum InstructionSerialization {
13 Base58,
15 #[default]
16 Base64,
18 Base58Legacy,
20}
21
22pub fn serialize_instruction(
24 ix: &Instruction,
25 format: InstructionSerialization,
26 payer: Option<&Pubkey>,
27) -> crate::Result<String> {
28 use solana_sdk::message::legacy::Message;
29
30 let message = match format {
31 InstructionSerialization::Base58
32 | InstructionSerialization::Base64
33 | InstructionSerialization::Base58Legacy => {
34 let message = Message::new(&[ix.clone()], payer);
35 match format {
36 InstructionSerialization::Base58 | InstructionSerialization::Base58Legacy => {
37 bs58::encode(message.serialize()).into_string()
38 }
39 InstructionSerialization::Base64 => STANDARD.encode(message.serialize()),
40 }
41 }
42 };
43
44 Ok(message)
45}
46
47pub fn serialize_message(
49 message: &solana_sdk::message::VersionedMessage,
50 format: InstructionSerialization,
51) -> crate::Result<String> {
52 let message = match format {
53 InstructionSerialization::Base58 => bs58::encode(message.serialize()).into_string(),
54 InstructionSerialization::Base64 => STANDARD.encode(message.serialize()),
55 InstructionSerialization::Base58Legacy => {
56 let message = to_legacy_message(message)?;
57 bs58::encode(message.serialize()).into_string()
58 }
59 };
60 Ok(message)
61}
62
63pub fn to_legacy_message<'a>(
65 message: &'a solana_sdk::message::VersionedMessage,
66) -> crate::Result<Cow<'a, solana_sdk::message::legacy::Message>> {
67 use solana_sdk::message::{legacy::Message, VersionedMessage};
68
69 match message {
70 VersionedMessage::Legacy(message) => Ok(Cow::Borrowed(message)),
71 VersionedMessage::V0(message) => {
72 if !message.address_table_lookups.is_empty() {
73 return Err(crate::Error::custom("a v0 message that includes address table lookups cannot be converted to a legacy message"));
74 }
75 Ok(Cow::Owned(Message {
76 header: message.header,
77 account_keys: message.account_keys.clone(),
78 recent_blockhash: message.recent_blockhash,
79 instructions: message.instructions.clone(),
80 }))
81 }
82 }
83}