1
0
mirror of https://github.com/mortdeus/legacy-cc.git synced 2026-10-09 12:22:24 +00:00
Files
mortdeus_legacy-cc/#_sniper (Rust) using jito Shred stream/parsers/pump_interface/src/instructions.rs
cryptoking1106 086ec82844 init
2025-09-18 18:12:50 -03:00

1773 lines
59 KiB
Rust

#[cfg(feature = "serde")]
// use crate::serializer::{deserialize_u128_as_string, serialize_u128_as_string};
use borsh::{BorshDeserialize, BorshSerialize};
use inflector::Inflector;
use solana_program::{
account_info::AccountInfo,
entrypoint::ProgramResult,
instruction::{AccountMeta, Instruction},
program::{invoke, invoke_signed},
program_error::ProgramError,
pubkey::Pubkey,
};
use std::io::Read;
// use std::fmt;
use strum_macros::{Display, EnumString};
#[derive(Clone, Debug, PartialEq, EnumString, Display)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum PumpProgramIx {
Initialize,
SetParams(SetParamsIxArgs),
Create(CreateIxArgs),
Buy(BuyIxArgs),
Sell(SellIxArgs),
Withdraw,
}
impl PumpProgramIx {
pub fn name(&self) -> String {
// Use the ToString derived method to get the enum variant name
self.to_string().to_camel_case()
}
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
match maybe_discm {
INITIALIZE_IX_DISCM => Ok(Self::Initialize),
SET_PARAMS_IX_DISCM => Ok(Self::SetParams(SetParamsIxArgs::deserialize(&mut reader)?)),
CREATE_IX_DISCM => Ok(Self::Create(CreateIxArgs::deserialize(&mut reader)?)),
BUY_IX_DISCM => Ok(Self::Buy(BuyIxArgs::deserialize(&mut reader)?)),
SELL_IX_DISCM => Ok(Self::Sell(SellIxArgs::deserialize(&mut reader)?)),
WITHDRAW_IX_DISCM => Ok(Self::Withdraw),
_ => Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("discm {:?} not found", maybe_discm),
)),
}
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
match self {
Self::Initialize => writer.write_all(&INITIALIZE_IX_DISCM),
Self::SetParams(args) => {
writer.write_all(&SET_PARAMS_IX_DISCM)?;
args.serialize(&mut writer)
}
Self::Create(args) => {
writer.write_all(&CREATE_IX_DISCM)?;
args.serialize(&mut writer)
}
Self::Buy(args) => {
writer.write_all(&BUY_IX_DISCM)?;
args.serialize(&mut writer)
}
Self::Sell(args) => {
writer.write_all(&SELL_IX_DISCM)?;
args.serialize(&mut writer)
}
Self::Withdraw => writer.write_all(&WITHDRAW_IX_DISCM),
}
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
fn invoke_instruction<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>(
ix: &Instruction,
accounts: A,
) -> ProgramResult {
let account_info: [AccountInfo<'info>; N] = accounts.into();
invoke(ix, &account_info)
}
fn invoke_instruction_signed<'info, A: Into<[AccountInfo<'info>; N]>, const N: usize>(
ix: &Instruction,
accounts: A,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let account_info: [AccountInfo<'info>; N] = accounts.into();
invoke_signed(ix, &account_info, seeds)
}
pub const INITIALIZE_IX_ACCOUNTS_LEN: usize = 3;
#[derive(Copy, Clone, Debug)]
pub struct InitializeAccounts<'me, 'info> {
pub global: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct InitializeKeys {
pub global: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
}
impl From<InitializeAccounts<'_, '_>> for InitializeKeys {
fn from(accounts: InitializeAccounts) -> Self {
Self {
global: *accounts.global.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
}
}
}
impl From<InitializeKeys> for [AccountMeta; INITIALIZE_IX_ACCOUNTS_LEN] {
fn from(keys: InitializeKeys) -> Self {
[
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; INITIALIZE_IX_ACCOUNTS_LEN]> for InitializeKeys {
fn from(pubkeys: [Pubkey; INITIALIZE_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: pubkeys[0],
user: pubkeys[1],
system_program: pubkeys[2],
}
}
}
impl<'info> From<InitializeAccounts<'_, 'info>>
for [AccountInfo<'info>; INITIALIZE_IX_ACCOUNTS_LEN]
{
fn from(accounts: InitializeAccounts<'_, 'info>) -> Self {
[
accounts.global.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; INITIALIZE_IX_ACCOUNTS_LEN]>
for InitializeAccounts<'me, 'info>
{
fn from(arr: &'me [AccountInfo<'info>; INITIALIZE_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: &arr[0],
user: &arr[1],
system_program: &arr[2],
}
}
}
pub const INITIALIZE_IX_DISCM: [u8; 8] = [175, 175, 109, 31, 13, 152, 155, 237];
#[derive(Clone, Debug, PartialEq)]
pub struct InitializeIxData;
impl InitializeIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != INITIALIZE_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
INITIALIZE_IX_DISCM, maybe_discm
),
));
}
Ok(Self)
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&INITIALIZE_IX_DISCM)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn initialize_ix_with_program_id(
program_id: Pubkey,
keys: InitializeKeys,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; INITIALIZE_IX_ACCOUNTS_LEN] = keys.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: InitializeIxData.try_to_vec()?,
})
}
pub fn initialize_ix(keys: InitializeKeys) -> std::io::Result<Instruction> {
initialize_ix_with_program_id(crate::ID, keys)
}
pub fn initialize_invoke_with_program_id(
program_id: Pubkey,
accounts: InitializeAccounts<'_, '_>,
) -> ProgramResult {
let keys: InitializeKeys = accounts.into();
let ix = initialize_ix_with_program_id(program_id, keys)?;
invoke_instruction(&ix, accounts)
}
pub fn initialize_invoke(accounts: InitializeAccounts<'_, '_>) -> ProgramResult {
initialize_invoke_with_program_id(crate::ID, accounts)
}
pub fn initialize_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: InitializeAccounts<'_, '_>,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: InitializeKeys = accounts.into();
let ix = initialize_ix_with_program_id(program_id, keys)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn initialize_invoke_signed(
accounts: InitializeAccounts<'_, '_>,
seeds: &[&[&[u8]]],
) -> ProgramResult {
initialize_invoke_signed_with_program_id(crate::ID, accounts, seeds)
}
pub fn initialize_verify_account_keys(
accounts: InitializeAccounts<'_, '_>,
keys: InitializeKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.global.key, keys.global),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn initialize_verify_writable_privileges<'me, 'info>(
accounts: InitializeAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [accounts.global, accounts.user] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn initialize_verify_signer_privileges<'me, 'info>(
accounts: InitializeAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn initialize_verify_account_privileges<'me, 'info>(
accounts: InitializeAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
initialize_verify_writable_privileges(accounts)?;
initialize_verify_signer_privileges(accounts)?;
Ok(())
}
pub const SET_PARAMS_IX_ACCOUNTS_LEN: usize = 5;
#[derive(Copy, Clone, Debug)]
pub struct SetParamsAccounts<'me, 'info> {
pub global: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
pub event_authority: &'me AccountInfo<'info>,
pub program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SetParamsKeys {
pub global: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
pub event_authority: Pubkey,
pub program: Pubkey,
}
impl From<SetParamsAccounts<'_, '_>> for SetParamsKeys {
fn from(accounts: SetParamsAccounts) -> Self {
Self {
global: *accounts.global.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
event_authority: *accounts.event_authority.key,
program: *accounts.program.key,
}
}
}
impl From<SetParamsKeys> for [AccountMeta; SET_PARAMS_IX_ACCOUNTS_LEN] {
fn from(keys: SetParamsKeys) -> Self {
[
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.event_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; SET_PARAMS_IX_ACCOUNTS_LEN]> for SetParamsKeys {
fn from(pubkeys: [Pubkey; SET_PARAMS_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: pubkeys[0],
user: pubkeys[1],
system_program: pubkeys[2],
event_authority: pubkeys[3],
program: pubkeys[4],
}
}
}
impl<'info> From<SetParamsAccounts<'_, 'info>>
for [AccountInfo<'info>; SET_PARAMS_IX_ACCOUNTS_LEN]
{
fn from(accounts: SetParamsAccounts<'_, 'info>) -> Self {
[
accounts.global.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
accounts.event_authority.clone(),
accounts.program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; SET_PARAMS_IX_ACCOUNTS_LEN]>
for SetParamsAccounts<'me, 'info>
{
fn from(arr: &'me [AccountInfo<'info>; SET_PARAMS_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: &arr[0],
user: &arr[1],
system_program: &arr[2],
event_authority: &arr[3],
program: &arr[4],
}
}
}
pub const SET_PARAMS_IX_DISCM: [u8; 8] = [27, 234, 178, 52, 147, 2, 187, 141];
#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SetParamsIxArgs {
pub fee_recipient: Pubkey,
pub initial_virtual_token_reserves: u64,
pub initial_virtual_sol_reserves: u64,
pub initial_real_token_reserves: u64,
pub token_total_supply: u64,
pub fee_basis_points: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct SetParamsIxData(pub SetParamsIxArgs);
impl From<SetParamsIxArgs> for SetParamsIxData {
fn from(args: SetParamsIxArgs) -> Self {
Self(args)
}
}
impl SetParamsIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != SET_PARAMS_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
SET_PARAMS_IX_DISCM, maybe_discm
),
));
}
Ok(Self(SetParamsIxArgs::deserialize(&mut reader)?))
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&SET_PARAMS_IX_DISCM)?;
self.0.serialize(&mut writer)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn set_params_ix_with_program_id(
program_id: Pubkey,
keys: SetParamsKeys,
args: SetParamsIxArgs,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; SET_PARAMS_IX_ACCOUNTS_LEN] = keys.into();
let data: SetParamsIxData = args.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: data.try_to_vec()?,
})
}
pub fn set_params_ix(keys: SetParamsKeys, args: SetParamsIxArgs) -> std::io::Result<Instruction> {
set_params_ix_with_program_id(crate::ID, keys, args)
}
pub fn set_params_invoke_with_program_id(
program_id: Pubkey,
accounts: SetParamsAccounts<'_, '_>,
args: SetParamsIxArgs,
) -> ProgramResult {
let keys: SetParamsKeys = accounts.into();
let ix = set_params_ix_with_program_id(program_id, keys, args)?;
invoke_instruction(&ix, accounts)
}
pub fn set_params_invoke(
accounts: SetParamsAccounts<'_, '_>,
args: SetParamsIxArgs,
) -> ProgramResult {
set_params_invoke_with_program_id(crate::ID, accounts, args)
}
pub fn set_params_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: SetParamsAccounts<'_, '_>,
args: SetParamsIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: SetParamsKeys = accounts.into();
let ix = set_params_ix_with_program_id(program_id, keys, args)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn set_params_invoke_signed(
accounts: SetParamsAccounts<'_, '_>,
args: SetParamsIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
set_params_invoke_signed_with_program_id(crate::ID, accounts, args, seeds)
}
pub fn set_params_verify_account_keys(
accounts: SetParamsAccounts<'_, '_>,
keys: SetParamsKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.global.key, keys.global),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
(*accounts.event_authority.key, keys.event_authority),
(*accounts.program.key, keys.program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn set_params_verify_writable_privileges<'me, 'info>(
accounts: SetParamsAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [accounts.global, accounts.user] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn set_params_verify_signer_privileges<'me, 'info>(
accounts: SetParamsAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn set_params_verify_account_privileges<'me, 'info>(
accounts: SetParamsAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
set_params_verify_writable_privileges(accounts)?;
set_params_verify_signer_privileges(accounts)?;
Ok(())
}
pub const CREATE_IX_ACCOUNTS_LEN: usize = 14;
#[derive(Copy, Clone, Debug)]
pub struct CreateAccounts<'me, 'info> {
pub mint: &'me AccountInfo<'info>,
pub mint_authority: &'me AccountInfo<'info>,
pub bonding_curve: &'me AccountInfo<'info>,
pub associated_bonding_curve: &'me AccountInfo<'info>,
pub global: &'me AccountInfo<'info>,
pub mpl_token_metadata: &'me AccountInfo<'info>,
pub metadata: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
pub token_program: &'me AccountInfo<'info>,
pub associated_token_program: &'me AccountInfo<'info>,
pub rent: &'me AccountInfo<'info>,
pub event_authority: &'me AccountInfo<'info>,
pub program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct CreateKeys {
pub mint: Pubkey,
pub mint_authority: Pubkey,
pub bonding_curve: Pubkey,
pub associated_bonding_curve: Pubkey,
pub global: Pubkey,
pub mpl_token_metadata: Pubkey,
pub metadata: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
pub token_program: Pubkey,
pub associated_token_program: Pubkey,
pub rent: Pubkey,
pub event_authority: Pubkey,
pub program: Pubkey,
}
impl From<CreateAccounts<'_, '_>> for CreateKeys {
fn from(accounts: CreateAccounts) -> Self {
Self {
mint: *accounts.mint.key,
mint_authority: *accounts.mint_authority.key,
bonding_curve: *accounts.bonding_curve.key,
associated_bonding_curve: *accounts.associated_bonding_curve.key,
global: *accounts.global.key,
mpl_token_metadata: *accounts.mpl_token_metadata.key,
metadata: *accounts.metadata.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
token_program: *accounts.token_program.key,
associated_token_program: *accounts.associated_token_program.key,
rent: *accounts.rent.key,
event_authority: *accounts.event_authority.key,
program: *accounts.program.key,
}
}
}
impl From<CreateKeys> for [AccountMeta; CREATE_IX_ACCOUNTS_LEN] {
fn from(keys: CreateKeys) -> Self {
[
AccountMeta {
pubkey: keys.mint,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.mint_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.mpl_token_metadata,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.metadata,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.associated_token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.rent,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.event_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; CREATE_IX_ACCOUNTS_LEN]> for CreateKeys {
fn from(pubkeys: [Pubkey; CREATE_IX_ACCOUNTS_LEN]) -> Self {
Self {
mint: pubkeys[0],
mint_authority: pubkeys[1],
bonding_curve: pubkeys[2],
associated_bonding_curve: pubkeys[3],
global: pubkeys[4],
mpl_token_metadata: pubkeys[5],
metadata: pubkeys[6],
user: pubkeys[7],
system_program: pubkeys[8],
token_program: pubkeys[9],
associated_token_program: pubkeys[10],
rent: pubkeys[11],
event_authority: pubkeys[12],
program: pubkeys[13],
}
}
}
impl<'info> From<CreateAccounts<'_, 'info>> for [AccountInfo<'info>; CREATE_IX_ACCOUNTS_LEN] {
fn from(accounts: CreateAccounts<'_, 'info>) -> Self {
[
accounts.mint.clone(),
accounts.mint_authority.clone(),
accounts.bonding_curve.clone(),
accounts.associated_bonding_curve.clone(),
accounts.global.clone(),
accounts.mpl_token_metadata.clone(),
accounts.metadata.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
accounts.token_program.clone(),
accounts.associated_token_program.clone(),
accounts.rent.clone(),
accounts.event_authority.clone(),
accounts.program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; CREATE_IX_ACCOUNTS_LEN]>
for CreateAccounts<'me, 'info>
{
fn from(arr: &'me [AccountInfo<'info>; CREATE_IX_ACCOUNTS_LEN]) -> Self {
Self {
mint: &arr[0],
mint_authority: &arr[1],
bonding_curve: &arr[2],
associated_bonding_curve: &arr[3],
global: &arr[4],
mpl_token_metadata: &arr[5],
metadata: &arr[6],
user: &arr[7],
system_program: &arr[8],
token_program: &arr[9],
associated_token_program: &arr[10],
rent: &arr[11],
event_authority: &arr[12],
program: &arr[13],
}
}
}
pub const CREATE_IX_DISCM: [u8; 8] = [24, 30, 200, 40, 5, 28, 7, 119];
#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CreateIxArgs {
pub name: String,
pub symbol: String,
pub uri: String,
pub creator: Pubkey,
}
#[derive(Clone, Debug, PartialEq)]
pub struct CreateIxData(pub CreateIxArgs);
impl From<CreateIxArgs> for CreateIxData {
fn from(args: CreateIxArgs) -> Self {
Self(args)
}
}
impl CreateIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != CREATE_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
CREATE_IX_DISCM, maybe_discm
),
));
}
Ok(Self(CreateIxArgs::deserialize(&mut reader)?))
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&CREATE_IX_DISCM)?;
self.0.serialize(&mut writer)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn create_ix_with_program_id(
program_id: Pubkey,
keys: CreateKeys,
args: CreateIxArgs,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; CREATE_IX_ACCOUNTS_LEN] = keys.into();
let data: CreateIxData = args.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: data.try_to_vec()?,
})
}
pub fn create_ix(keys: CreateKeys, args: CreateIxArgs) -> std::io::Result<Instruction> {
create_ix_with_program_id(crate::ID, keys, args)
}
pub fn create_invoke_with_program_id(
program_id: Pubkey,
accounts: CreateAccounts<'_, '_>,
args: CreateIxArgs,
) -> ProgramResult {
let keys: CreateKeys = accounts.into();
let ix = create_ix_with_program_id(program_id, keys, args)?;
invoke_instruction(&ix, accounts)
}
pub fn create_invoke(accounts: CreateAccounts<'_, '_>, args: CreateIxArgs) -> ProgramResult {
create_invoke_with_program_id(crate::ID, accounts, args)
}
pub fn create_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: CreateAccounts<'_, '_>,
args: CreateIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: CreateKeys = accounts.into();
let ix = create_ix_with_program_id(program_id, keys, args)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn create_invoke_signed(
accounts: CreateAccounts<'_, '_>,
args: CreateIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
create_invoke_signed_with_program_id(crate::ID, accounts, args, seeds)
}
pub fn create_verify_account_keys(
accounts: CreateAccounts<'_, '_>,
keys: CreateKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.mint.key, keys.mint),
(*accounts.mint_authority.key, keys.mint_authority),
(*accounts.bonding_curve.key, keys.bonding_curve),
(
*accounts.associated_bonding_curve.key,
keys.associated_bonding_curve,
),
(*accounts.global.key, keys.global),
(*accounts.mpl_token_metadata.key, keys.mpl_token_metadata),
(*accounts.metadata.key, keys.metadata),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
(*accounts.token_program.key, keys.token_program),
(
*accounts.associated_token_program.key,
keys.associated_token_program,
),
(*accounts.rent.key, keys.rent),
(*accounts.event_authority.key, keys.event_authority),
(*accounts.program.key, keys.program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn create_verify_writable_privileges<'me, 'info>(
accounts: CreateAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [
accounts.mint,
accounts.bonding_curve,
accounts.associated_bonding_curve,
accounts.metadata,
accounts.user,
] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn create_verify_signer_privileges<'me, 'info>(
accounts: CreateAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.mint, accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn create_verify_account_privileges<'me, 'info>(
accounts: CreateAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
create_verify_writable_privileges(accounts)?;
create_verify_signer_privileges(accounts)?;
Ok(())
}
pub const BUY_IX_ACCOUNTS_LEN: usize = 12;
#[derive(Copy, Clone, Debug)]
pub struct BuyAccounts<'me, 'info> {
pub global: &'me AccountInfo<'info>,
pub fee_recipient: &'me AccountInfo<'info>,
pub mint: &'me AccountInfo<'info>,
pub bonding_curve: &'me AccountInfo<'info>,
pub associated_bonding_curve: &'me AccountInfo<'info>,
pub associated_user: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
pub token_program: &'me AccountInfo<'info>,
pub rent: &'me AccountInfo<'info>,
pub event_authority: &'me AccountInfo<'info>,
pub program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct BuyKeys {
pub global: Pubkey,
pub fee_recipient: Pubkey,
pub mint: Pubkey,
pub bonding_curve: Pubkey,
pub associated_bonding_curve: Pubkey,
pub associated_user: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
pub token_program: Pubkey,
pub rent: Pubkey,
pub event_authority: Pubkey,
pub program: Pubkey,
}
impl From<BuyAccounts<'_, '_>> for BuyKeys {
fn from(accounts: BuyAccounts) -> Self {
Self {
global: *accounts.global.key,
fee_recipient: *accounts.fee_recipient.key,
mint: *accounts.mint.key,
bonding_curve: *accounts.bonding_curve.key,
associated_bonding_curve: *accounts.associated_bonding_curve.key,
associated_user: *accounts.associated_user.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
token_program: *accounts.token_program.key,
rent: *accounts.rent.key,
event_authority: *accounts.event_authority.key,
program: *accounts.program.key,
}
}
}
impl From<BuyKeys> for [AccountMeta; BUY_IX_ACCOUNTS_LEN] {
fn from(keys: BuyKeys) -> Self {
[
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.fee_recipient,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.mint,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_user,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.rent,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.event_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; BUY_IX_ACCOUNTS_LEN]> for BuyKeys {
fn from(pubkeys: [Pubkey; BUY_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: pubkeys[0],
fee_recipient: pubkeys[1],
mint: pubkeys[2],
bonding_curve: pubkeys[3],
associated_bonding_curve: pubkeys[4],
associated_user: pubkeys[5],
user: pubkeys[6],
system_program: pubkeys[7],
token_program: pubkeys[8],
rent: pubkeys[9],
event_authority: pubkeys[10],
program: pubkeys[11],
}
}
}
impl<'info> From<BuyAccounts<'_, 'info>> for [AccountInfo<'info>; BUY_IX_ACCOUNTS_LEN] {
fn from(accounts: BuyAccounts<'_, 'info>) -> Self {
[
accounts.global.clone(),
accounts.fee_recipient.clone(),
accounts.mint.clone(),
accounts.bonding_curve.clone(),
accounts.associated_bonding_curve.clone(),
accounts.associated_user.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
accounts.token_program.clone(),
accounts.rent.clone(),
accounts.event_authority.clone(),
accounts.program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; BUY_IX_ACCOUNTS_LEN]> for BuyAccounts<'me, 'info> {
fn from(arr: &'me [AccountInfo<'info>; BUY_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: &arr[0],
fee_recipient: &arr[1],
mint: &arr[2],
bonding_curve: &arr[3],
associated_bonding_curve: &arr[4],
associated_user: &arr[5],
user: &arr[6],
system_program: &arr[7],
token_program: &arr[8],
rent: &arr[9],
event_authority: &arr[10],
program: &arr[11],
}
}
}
pub const BUY_IX_DISCM: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BuyIxArgs {
pub amount: u64,
pub max_sol_cost: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct BuyIxData(pub BuyIxArgs);
impl From<BuyIxArgs> for BuyIxData {
fn from(args: BuyIxArgs) -> Self {
Self(args)
}
}
impl BuyIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != BUY_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
BUY_IX_DISCM, maybe_discm
),
));
}
Ok(Self(BuyIxArgs::deserialize(&mut reader)?))
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&BUY_IX_DISCM)?;
self.0.serialize(&mut writer)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn buy_ix_with_program_id(
program_id: Pubkey,
keys: BuyKeys,
args: BuyIxArgs,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; BUY_IX_ACCOUNTS_LEN] = keys.into();
let data: BuyIxData = args.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: data.try_to_vec()?,
})
}
pub fn buy_ix(keys: BuyKeys, args: BuyIxArgs) -> std::io::Result<Instruction> {
buy_ix_with_program_id(crate::ID, keys, args)
}
pub fn buy_invoke_with_program_id(
program_id: Pubkey,
accounts: BuyAccounts<'_, '_>,
args: BuyIxArgs,
) -> ProgramResult {
let keys: BuyKeys = accounts.into();
let ix = buy_ix_with_program_id(program_id, keys, args)?;
invoke_instruction(&ix, accounts)
}
pub fn buy_invoke(accounts: BuyAccounts<'_, '_>, args: BuyIxArgs) -> ProgramResult {
buy_invoke_with_program_id(crate::ID, accounts, args)
}
pub fn buy_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: BuyAccounts<'_, '_>,
args: BuyIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: BuyKeys = accounts.into();
let ix = buy_ix_with_program_id(program_id, keys, args)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn buy_invoke_signed(
accounts: BuyAccounts<'_, '_>,
args: BuyIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
buy_invoke_signed_with_program_id(crate::ID, accounts, args, seeds)
}
pub fn buy_verify_account_keys(
accounts: BuyAccounts<'_, '_>,
keys: BuyKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.global.key, keys.global),
(*accounts.fee_recipient.key, keys.fee_recipient),
(*accounts.mint.key, keys.mint),
(*accounts.bonding_curve.key, keys.bonding_curve),
(
*accounts.associated_bonding_curve.key,
keys.associated_bonding_curve,
),
(*accounts.associated_user.key, keys.associated_user),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
(*accounts.token_program.key, keys.token_program),
(*accounts.rent.key, keys.rent),
(*accounts.event_authority.key, keys.event_authority),
(*accounts.program.key, keys.program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn buy_verify_writable_privileges<'me, 'info>(
accounts: BuyAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [
accounts.fee_recipient,
accounts.bonding_curve,
accounts.associated_bonding_curve,
accounts.associated_user,
accounts.user,
] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn buy_verify_signer_privileges<'me, 'info>(
accounts: BuyAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn buy_verify_account_privileges<'me, 'info>(
accounts: BuyAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
buy_verify_writable_privileges(accounts)?;
buy_verify_signer_privileges(accounts)?;
Ok(())
}
pub const SELL_IX_ACCOUNTS_LEN: usize = 12;
#[derive(Copy, Clone, Debug)]
pub struct SellAccounts<'me, 'info> {
pub global: &'me AccountInfo<'info>,
pub fee_recipient: &'me AccountInfo<'info>,
pub mint: &'me AccountInfo<'info>,
pub bonding_curve: &'me AccountInfo<'info>,
pub associated_bonding_curve: &'me AccountInfo<'info>,
pub associated_user: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
pub associated_token_program: &'me AccountInfo<'info>,
pub token_program: &'me AccountInfo<'info>,
pub event_authority: &'me AccountInfo<'info>,
pub program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct SellKeys {
pub global: Pubkey,
pub fee_recipient: Pubkey,
pub mint: Pubkey,
pub bonding_curve: Pubkey,
pub associated_bonding_curve: Pubkey,
pub associated_user: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
pub associated_token_program: Pubkey,
pub token_program: Pubkey,
pub event_authority: Pubkey,
pub program: Pubkey,
}
impl From<SellAccounts<'_, '_>> for SellKeys {
fn from(accounts: SellAccounts) -> Self {
Self {
global: *accounts.global.key,
fee_recipient: *accounts.fee_recipient.key,
mint: *accounts.mint.key,
bonding_curve: *accounts.bonding_curve.key,
associated_bonding_curve: *accounts.associated_bonding_curve.key,
associated_user: *accounts.associated_user.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
associated_token_program: *accounts.associated_token_program.key,
token_program: *accounts.token_program.key,
event_authority: *accounts.event_authority.key,
program: *accounts.program.key,
}
}
}
impl From<SellKeys> for [AccountMeta; SELL_IX_ACCOUNTS_LEN] {
fn from(keys: SellKeys) -> Self {
[
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.fee_recipient,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.mint,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_user,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.associated_token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.event_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; SELL_IX_ACCOUNTS_LEN]> for SellKeys {
fn from(pubkeys: [Pubkey; SELL_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: pubkeys[0],
fee_recipient: pubkeys[1],
mint: pubkeys[2],
bonding_curve: pubkeys[3],
associated_bonding_curve: pubkeys[4],
associated_user: pubkeys[5],
user: pubkeys[6],
system_program: pubkeys[7],
associated_token_program: pubkeys[8],
token_program: pubkeys[9],
event_authority: pubkeys[10],
program: pubkeys[11],
}
}
}
impl<'info> From<SellAccounts<'_, 'info>> for [AccountInfo<'info>; SELL_IX_ACCOUNTS_LEN] {
fn from(accounts: SellAccounts<'_, 'info>) -> Self {
[
accounts.global.clone(),
accounts.fee_recipient.clone(),
accounts.mint.clone(),
accounts.bonding_curve.clone(),
accounts.associated_bonding_curve.clone(),
accounts.associated_user.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
accounts.associated_token_program.clone(),
accounts.token_program.clone(),
accounts.event_authority.clone(),
accounts.program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; SELL_IX_ACCOUNTS_LEN]>
for SellAccounts<'me, 'info>
{
fn from(arr: &'me [AccountInfo<'info>; SELL_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: &arr[0],
fee_recipient: &arr[1],
mint: &arr[2],
bonding_curve: &arr[3],
associated_bonding_curve: &arr[4],
associated_user: &arr[5],
user: &arr[6],
system_program: &arr[7],
associated_token_program: &arr[8],
token_program: &arr[9],
event_authority: &arr[10],
program: &arr[11],
}
}
}
pub const SELL_IX_DISCM: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SellIxArgs {
pub amount: u64,
pub min_sol_output: u64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct SellIxData(pub SellIxArgs);
impl From<SellIxArgs> for SellIxData {
fn from(args: SellIxArgs) -> Self {
Self(args)
}
}
impl SellIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != SELL_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
SELL_IX_DISCM, maybe_discm
),
));
}
Ok(Self(SellIxArgs::deserialize(&mut reader)?))
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&SELL_IX_DISCM)?;
self.0.serialize(&mut writer)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn sell_ix_with_program_id(
program_id: Pubkey,
keys: SellKeys,
args: SellIxArgs,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; SELL_IX_ACCOUNTS_LEN] = keys.into();
let data: SellIxData = args.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: data.try_to_vec()?,
})
}
pub fn sell_ix(keys: SellKeys, args: SellIxArgs) -> std::io::Result<Instruction> {
sell_ix_with_program_id(crate::ID, keys, args)
}
pub fn sell_invoke_with_program_id(
program_id: Pubkey,
accounts: SellAccounts<'_, '_>,
args: SellIxArgs,
) -> ProgramResult {
let keys: SellKeys = accounts.into();
let ix = sell_ix_with_program_id(program_id, keys, args)?;
invoke_instruction(&ix, accounts)
}
pub fn sell_invoke(accounts: SellAccounts<'_, '_>, args: SellIxArgs) -> ProgramResult {
sell_invoke_with_program_id(crate::ID, accounts, args)
}
pub fn sell_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: SellAccounts<'_, '_>,
args: SellIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: SellKeys = accounts.into();
let ix = sell_ix_with_program_id(program_id, keys, args)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn sell_invoke_signed(
accounts: SellAccounts<'_, '_>,
args: SellIxArgs,
seeds: &[&[&[u8]]],
) -> ProgramResult {
sell_invoke_signed_with_program_id(crate::ID, accounts, args, seeds)
}
pub fn sell_verify_account_keys(
accounts: SellAccounts<'_, '_>,
keys: SellKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.global.key, keys.global),
(*accounts.fee_recipient.key, keys.fee_recipient),
(*accounts.mint.key, keys.mint),
(*accounts.bonding_curve.key, keys.bonding_curve),
(
*accounts.associated_bonding_curve.key,
keys.associated_bonding_curve,
),
(*accounts.associated_user.key, keys.associated_user),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
(
*accounts.associated_token_program.key,
keys.associated_token_program,
),
(*accounts.token_program.key, keys.token_program),
(*accounts.event_authority.key, keys.event_authority),
(*accounts.program.key, keys.program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn sell_verify_writable_privileges<'me, 'info>(
accounts: SellAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [
accounts.fee_recipient,
accounts.bonding_curve,
accounts.associated_bonding_curve,
accounts.associated_user,
accounts.user,
] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn sell_verify_signer_privileges<'me, 'info>(
accounts: SellAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn sell_verify_account_privileges<'me, 'info>(
accounts: SellAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
sell_verify_writable_privileges(accounts)?;
sell_verify_signer_privileges(accounts)?;
Ok(())
}
pub const WITHDRAW_IX_ACCOUNTS_LEN: usize = 11;
#[derive(Copy, Clone, Debug)]
pub struct WithdrawAccounts<'me, 'info> {
pub global: &'me AccountInfo<'info>,
pub mint: &'me AccountInfo<'info>,
pub bonding_curve: &'me AccountInfo<'info>,
pub associated_bonding_curve: &'me AccountInfo<'info>,
pub associated_user: &'me AccountInfo<'info>,
pub user: &'me AccountInfo<'info>,
pub system_program: &'me AccountInfo<'info>,
pub token_program: &'me AccountInfo<'info>,
pub rent: &'me AccountInfo<'info>,
pub event_authority: &'me AccountInfo<'info>,
pub program: &'me AccountInfo<'info>,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct WithdrawKeys {
pub global: Pubkey,
pub mint: Pubkey,
pub bonding_curve: Pubkey,
pub associated_bonding_curve: Pubkey,
pub associated_user: Pubkey,
pub user: Pubkey,
pub system_program: Pubkey,
pub token_program: Pubkey,
pub rent: Pubkey,
pub event_authority: Pubkey,
pub program: Pubkey,
}
impl From<WithdrawAccounts<'_, '_>> for WithdrawKeys {
fn from(accounts: WithdrawAccounts) -> Self {
Self {
global: *accounts.global.key,
mint: *accounts.mint.key,
bonding_curve: *accounts.bonding_curve.key,
associated_bonding_curve: *accounts.associated_bonding_curve.key,
associated_user: *accounts.associated_user.key,
user: *accounts.user.key,
system_program: *accounts.system_program.key,
token_program: *accounts.token_program.key,
rent: *accounts.rent.key,
event_authority: *accounts.event_authority.key,
program: *accounts.program.key,
}
}
}
impl From<WithdrawKeys> for [AccountMeta; WITHDRAW_IX_ACCOUNTS_LEN] {
fn from(keys: WithdrawKeys) -> Self {
[
AccountMeta {
pubkey: keys.global,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.mint,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_bonding_curve,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.associated_user,
is_signer: false,
is_writable: true,
},
AccountMeta {
pubkey: keys.user,
is_signer: true,
is_writable: true,
},
AccountMeta {
pubkey: keys.system_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.token_program,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.rent,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.event_authority,
is_signer: false,
is_writable: false,
},
AccountMeta {
pubkey: keys.program,
is_signer: false,
is_writable: false,
},
]
}
}
impl From<[Pubkey; WITHDRAW_IX_ACCOUNTS_LEN]> for WithdrawKeys {
fn from(pubkeys: [Pubkey; WITHDRAW_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: pubkeys[0],
mint: pubkeys[1],
bonding_curve: pubkeys[2],
associated_bonding_curve: pubkeys[3],
associated_user: pubkeys[4],
user: pubkeys[5],
system_program: pubkeys[6],
token_program: pubkeys[7],
rent: pubkeys[8],
event_authority: pubkeys[9],
program: pubkeys[10],
}
}
}
impl<'info> From<WithdrawAccounts<'_, 'info>> for [AccountInfo<'info>; WITHDRAW_IX_ACCOUNTS_LEN] {
fn from(accounts: WithdrawAccounts<'_, 'info>) -> Self {
[
accounts.global.clone(),
accounts.mint.clone(),
accounts.bonding_curve.clone(),
accounts.associated_bonding_curve.clone(),
accounts.associated_user.clone(),
accounts.user.clone(),
accounts.system_program.clone(),
accounts.token_program.clone(),
accounts.rent.clone(),
accounts.event_authority.clone(),
accounts.program.clone(),
]
}
}
impl<'me, 'info> From<&'me [AccountInfo<'info>; WITHDRAW_IX_ACCOUNTS_LEN]>
for WithdrawAccounts<'me, 'info>
{
fn from(arr: &'me [AccountInfo<'info>; WITHDRAW_IX_ACCOUNTS_LEN]) -> Self {
Self {
global: &arr[0],
mint: &arr[1],
bonding_curve: &arr[2],
associated_bonding_curve: &arr[3],
associated_user: &arr[4],
user: &arr[5],
system_program: &arr[6],
token_program: &arr[7],
rent: &arr[8],
event_authority: &arr[9],
program: &arr[10],
}
}
}
pub const WITHDRAW_IX_DISCM: [u8; 8] = [183, 18, 70, 156, 148, 109, 161, 34];
#[derive(Clone, Debug, PartialEq)]
pub struct WithdrawIxData;
impl WithdrawIxData {
pub fn deserialize(buf: &[u8]) -> std::io::Result<Self> {
let mut reader = buf;
let mut maybe_discm = [0u8; 8];
reader.read_exact(&mut maybe_discm)?;
if maybe_discm != WITHDRAW_IX_DISCM {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!(
"discm does not match. Expected: {:?}. Received: {:?}",
WITHDRAW_IX_DISCM, maybe_discm
),
));
}
Ok(Self)
}
pub fn serialize<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
writer.write_all(&WITHDRAW_IX_DISCM)
}
pub fn try_to_vec(&self) -> std::io::Result<Vec<u8>> {
let mut data = Vec::new();
self.serialize(&mut data)?;
Ok(data)
}
}
pub fn withdraw_ix_with_program_id(
program_id: Pubkey,
keys: WithdrawKeys,
) -> std::io::Result<Instruction> {
let metas: [AccountMeta; WITHDRAW_IX_ACCOUNTS_LEN] = keys.into();
Ok(Instruction {
program_id,
accounts: Vec::from(metas),
data: WithdrawIxData.try_to_vec()?,
})
}
pub fn withdraw_ix(keys: WithdrawKeys) -> std::io::Result<Instruction> {
withdraw_ix_with_program_id(crate::ID, keys)
}
pub fn withdraw_invoke_with_program_id(
program_id: Pubkey,
accounts: WithdrawAccounts<'_, '_>,
) -> ProgramResult {
let keys: WithdrawKeys = accounts.into();
let ix = withdraw_ix_with_program_id(program_id, keys)?;
invoke_instruction(&ix, accounts)
}
pub fn withdraw_invoke(accounts: WithdrawAccounts<'_, '_>) -> ProgramResult {
withdraw_invoke_with_program_id(crate::ID, accounts)
}
pub fn withdraw_invoke_signed_with_program_id(
program_id: Pubkey,
accounts: WithdrawAccounts<'_, '_>,
seeds: &[&[&[u8]]],
) -> ProgramResult {
let keys: WithdrawKeys = accounts.into();
let ix = withdraw_ix_with_program_id(program_id, keys)?;
invoke_instruction_signed(&ix, accounts, seeds)
}
pub fn withdraw_invoke_signed(
accounts: WithdrawAccounts<'_, '_>,
seeds: &[&[&[u8]]],
) -> ProgramResult {
withdraw_invoke_signed_with_program_id(crate::ID, accounts, seeds)
}
pub fn withdraw_verify_account_keys(
accounts: WithdrawAccounts<'_, '_>,
keys: WithdrawKeys,
) -> Result<(), (Pubkey, Pubkey)> {
for (actual, expected) in [
(*accounts.global.key, keys.global),
(*accounts.mint.key, keys.mint),
(*accounts.bonding_curve.key, keys.bonding_curve),
(
*accounts.associated_bonding_curve.key,
keys.associated_bonding_curve,
),
(*accounts.associated_user.key, keys.associated_user),
(*accounts.user.key, keys.user),
(*accounts.system_program.key, keys.system_program),
(*accounts.token_program.key, keys.token_program),
(*accounts.rent.key, keys.rent),
(*accounts.event_authority.key, keys.event_authority),
(*accounts.program.key, keys.program),
] {
if actual != expected {
return Err((actual, expected));
}
}
Ok(())
}
pub fn withdraw_verify_writable_privileges<'me, 'info>(
accounts: WithdrawAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_writable in [
accounts.bonding_curve,
accounts.associated_bonding_curve,
accounts.associated_user,
accounts.user,
] {
if !should_be_writable.is_writable {
return Err((should_be_writable, ProgramError::InvalidAccountData));
}
}
Ok(())
}
pub fn withdraw_verify_signer_privileges<'me, 'info>(
accounts: WithdrawAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
for should_be_signer in [accounts.user] {
if !should_be_signer.is_signer {
return Err((should_be_signer, ProgramError::MissingRequiredSignature));
}
}
Ok(())
}
pub fn withdraw_verify_account_privileges<'me, 'info>(
accounts: WithdrawAccounts<'me, 'info>,
) -> Result<(), (&'me AccountInfo<'info>, ProgramError)> {
withdraw_verify_writable_privileges(accounts)?;
withdraw_verify_signer_privileges(accounts)?;
Ok(())
}