devol_accounts_kit/instructions_data/as_transaction_instruction/
withdraw_token.rs

1use std::error::Error;
2use std::str::FromStr;
3use async_trait::async_trait;
4use solana_program::instruction::{AccountMeta, Instruction};
5use solana_program::pubkey::Pubkey;
6use crate::account_readers::dvl_readable::DvlIndexParam;
7use crate::accounts::mints::mint_log::mint_log_account::MintLogAccount;
8use crate::accounts::mints::mints_account::MintsAccount;
9use crate::accounts::root::root_account::RootAccount;
10use crate::constants::TOKEN_PROGRAM_ID;
11use crate::dvl_client::dvl_client::DvlClient;
12use crate::instructions_data::as_transaction_instruction::as_transaction_instruction::AsTransactionInstruction;
13use crate::instructions_data::dvl_instruction_data::DvlInstructionData;
14use crate::instructions_data::withdraw_token::InstructionWithdrawToken;
15
16pub struct WithdrawTokenTransactionParams {
17    pub mint_id: u32,
18    pub client_key: Pubkey,
19}
20
21#[async_trait]
22impl AsTransactionInstruction for InstructionWithdrawToken {
23    type DvlTransactionInstructionParams = WithdrawTokenTransactionParams;
24
25
26    async fn as_transaction_instruction(
27        &self,
28        client: &DvlClient,
29        signer: &Pubkey,
30        transaction_params: Self::DvlTransactionInstructionParams,
31    ) -> Result<Box<Instruction>, Box<dyn Error>> {
32        let data = self.to_vec_le();
33        let root_acc_key = client.account_public_key::<RootAccount>(()).await?;
34        let mint_acc_key = client.account_public_key::<MintsAccount>(()).await?;
35        let mints_acc = client.get_account::<MintsAccount>(()).await?;
36        let mints_program_acc_key = mints_acc.data[transaction_params.mint_id as usize].program_address;
37        let mints_address_acc_key = mints_acc.data[transaction_params.mint_id as usize].address;
38        let client_acc_key = transaction_params.client_key;
39        let log_acc_key = client.account_public_key::<MintLogAccount>(DvlIndexParam { id: transaction_params.mint_id }).await?;
40        let pda = Pubkey::create_program_address(
41            &["devol".as_bytes()],
42            &client.program_id,
43        )?;
44        let token_program_id_key = Pubkey::from_str(TOKEN_PROGRAM_ID)?;
45
46        let account_metas = Vec::from([
47            AccountMeta {
48                pubkey: *signer,
49                is_signer: true,
50                is_writable: false,
51            },
52            AccountMeta {
53                pubkey: *root_acc_key,
54                is_signer: false,
55                is_writable: true,
56            },
57            AccountMeta {
58                pubkey: mints_program_acc_key,
59                is_signer: false,
60                is_writable: true,
61            },
62            AccountMeta {
63                pubkey: *mint_acc_key,
64                is_signer: false,
65                is_writable: false,
66            },
67            AccountMeta {
68                pubkey: token_program_id_key,
69                is_signer: false,
70                is_writable: false,
71            },
72            AccountMeta {
73                pubkey: client_acc_key,
74                is_signer: false,
75                is_writable: true,
76            },
77            AccountMeta {
78                pubkey: pda,
79                is_signer: false,
80                is_writable: false,
81            },
82            AccountMeta {
83                pubkey: *log_acc_key,
84                is_signer: false,
85                is_writable: true,
86            },
87            AccountMeta {
88                pubkey: mints_address_acc_key,
89                is_signer: false,
90                is_writable: true,
91            },
92        ]);
93        Ok(Box::from(Instruction::new_with_bytes(
94            client.program_id,
95            &*data,
96            account_metas,
97        )))
98    }
99}