hodor_program/
processor.rs

1use solana_program::account_info::AccountInfo;
2use solana_program::entrypoint::ProgramResult;
3use solana_program::program_error::ProgramError::InvalidInstructionData;
4use solana_program::pubkey::Pubkey;
5use solana_program::program_pack::Pack;
6use solana_program::program::{invoke, invoke_signed};
7use solana_program::rent::Rent;
8use solana_program::sysvar::Sysvar;
9use crate::swap;
10
11pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], instruction_data: &[u8]) -> ProgramResult {
12    let module_tag = instruction_data.first().ok_or(InvalidInstructionData)?;
13
14    match module_tag {
15        1 => {
16            swap::processor::process(program_id, accounts, instruction_data)
17        },
18        _ => Err(InvalidInstructionData),
19    }
20}
21
22pub(crate) fn create_spl_token_account<'a>(
23    account: &AccountInfo<'a>, mint: &AccountInfo<'a>, owner: &AccountInfo<'a>, fee_payer: &AccountInfo<'a>, seeds: &[&[u8]],
24    program_id: &Pubkey, spl_token_program: &AccountInfo<'a>, system_program: &AccountInfo<'a>
25) -> ProgramResult {
26    let rent = Rent::get()?;
27    let (token_account, bump_seed) = Pubkey::find_program_address(&seeds, program_id);
28    // todo: should we check account.key == token_account ? Below instructions should fail if it's not true
29
30    let create_account_instruction = solana_program::system_instruction::create_account(
31        &fee_payer.key,
32        &token_account,
33        rent.minimum_balance(spl_token::state::Account::LEN),
34        spl_token::state::Account::LEN as u64,
35        &spl_token::id(),
36    );
37
38    invoke_signed(
39        &create_account_instruction,
40        &[
41            system_program.clone(),
42            fee_payer.clone(),
43            account.clone(),
44        ],
45        &[&[&seeds[0], &seeds[1], &[bump_seed]]], // todo seeds explode
46    )?;
47
48    let spl_initialize_instruction = spl_token::instruction::initialize_account3(
49        &spl_token_program.key,
50        &token_account,
51        &mint.key,
52        &owner.key,
53    )?;
54
55    invoke(
56        &spl_initialize_instruction,
57        &[
58            spl_token_program.clone(),
59            account.clone(),
60            mint.clone(),
61        ],
62    )?;
63
64    Ok(())
65}
66
67
68pub(crate) fn transfer_spl_token<'a>(source: &AccountInfo<'a>, destination: &AccountInfo<'a>, owner: &AccountInfo<'a>,
69                                     spl_token_program: &AccountInfo<'a>, amount: u64) -> ProgramResult {
70    let transfer_instruction = spl_token::instruction::transfer(
71        &spl_token_program.key,
72        &source.key,
73        &destination.key,
74        &owner.key,
75        &[&owner.key],
76        amount,
77    )?;
78
79    invoke(
80        &transfer_instruction,
81        &[
82            spl_token_program.clone(),
83            source.clone(),
84            destination.clone(),
85            owner.clone(),
86        ],
87    )?;
88
89    Ok(())
90}