manifest/program/instruction_builders/
swap_v2_instruction.rs

1use crate::{
2    program::{swap::SwapParams, ManifestInstruction},
3    validation::{get_global_address, get_global_vault_address, get_vault_address},
4};
5use borsh::BorshSerialize;
6use solana_program::{
7    instruction::{AccountMeta, Instruction},
8    pubkey::Pubkey,
9};
10
11#[allow(clippy::too_many_arguments)]
12pub fn swap_v2_instruction(
13    market: &Pubkey,
14    payer: &Pubkey,
15    owner: &Pubkey,
16    base_mint: &Pubkey,
17    quote_mint: &Pubkey,
18    trader_base_account: &Pubkey,
19    trader_quote_account: &Pubkey,
20    in_atoms: u64,
21    out_atoms: u64,
22    is_base_in: bool,
23    is_exact_in: bool,
24    token_program_base: Pubkey,
25    token_program_quote: Pubkey,
26    include_global: bool,
27) -> Instruction {
28    let (vault_base_account, _) = get_vault_address(market, base_mint);
29    let (vault_quote_account, _) = get_vault_address(market, quote_mint);
30    let mut account_metas: Vec<AccountMeta> = vec![
31        AccountMeta::new_readonly(*payer, true),
32        AccountMeta::new_readonly(*owner, true),
33        AccountMeta::new(*market, false),
34        AccountMeta::new_readonly(solana_program::system_program::id(), false),
35        AccountMeta::new(*trader_base_account, false),
36        AccountMeta::new(*trader_quote_account, false),
37        AccountMeta::new(vault_base_account, false),
38        AccountMeta::new(vault_quote_account, false),
39        AccountMeta::new_readonly(token_program_base, false),
40    ];
41    if token_program_base == spl_token_2022::id() {
42        account_metas.push(AccountMeta::new_readonly(*base_mint, false))
43    }
44    if token_program_base != token_program_quote {
45        account_metas.push(AccountMeta::new_readonly(token_program_quote, false))
46    }
47    if token_program_quote == spl_token_2022::id() {
48        account_metas.push(AccountMeta::new(*quote_mint, false))
49    }
50    if include_global {
51        let global_mint: &Pubkey = if is_base_in { quote_mint } else { base_mint };
52        let (global, _) = get_global_address(global_mint);
53        let (global_vault, _) = get_global_vault_address(global_mint);
54        account_metas.push(AccountMeta::new(global, false));
55        account_metas.push(AccountMeta::new(global_vault, false));
56    }
57
58    Instruction {
59        program_id: crate::id(),
60        accounts: account_metas,
61        data: [
62            ManifestInstruction::Swap.to_vec(),
63            SwapParams::new(in_atoms, out_atoms, is_base_in, is_exact_in)
64                .try_to_vec()
65                .unwrap(),
66        ]
67        .concat(),
68    }
69}