Skip to main content

hpsvm_token/
close_account.rs

1use hpsvm::{HPSVM, types::FailedTransactionMetadata};
2use smallvec::{SmallVec, smallvec};
3use solana_address::Address;
4use solana_keypair::Keypair;
5use solana_signer::{Signer, signers::Signers};
6
7use super::{TOKEN_ID, get_multisig_signers, spl_token::instruction::close_account};
8
9/// ### Description
10/// Builder for the [`close_account`] instruction.
11///
12/// ### Optional fields
13/// - `owner`: `payer` by default.
14/// - `token_program_id`: [`TOKEN_ID`] by default.
15#[derive(Debug)]
16pub struct CloseAccount<'a> {
17    svm: &'a mut HPSVM,
18    payer: &'a Keypair,
19    account: &'a Address,
20    destination: &'a Address,
21    token_program_id: Option<&'a Address>,
22    signers: SmallVec<[&'a Keypair; 1]>,
23    owner: Option<Address>,
24}
25
26impl<'a> CloseAccount<'a> {
27    /// Creates a new instance of [`close_account`] instruction.
28    pub fn new(
29        svm: &'a mut HPSVM,
30        payer: &'a Keypair,
31        account: &'a Address,
32        destination: &'a Address,
33    ) -> Self {
34        CloseAccount {
35            svm,
36            payer,
37            account,
38            destination,
39            owner: None,
40            signers: smallvec![payer],
41            token_program_id: None,
42        }
43    }
44
45    /// Sets the owner of the account with single owner.
46    pub fn owner(mut self, owner: &'a Keypair) -> Self {
47        self.owner = Some(owner.pubkey());
48        self.signers = smallvec![owner];
49        self
50    }
51
52    /// Sets the owner of the account with multisig owner.
53    pub fn multisig(mut self, multisig: &'a Address, signers: &'a [&'a Keypair]) -> Self {
54        self.owner = Some(*multisig);
55        self.signers = SmallVec::from(signers);
56        self
57    }
58
59    /// Sets the token program id for the instruction.
60    pub fn token_program_id(mut self, program_id: &'a Address) -> Self {
61        self.token_program_id = Some(program_id);
62        self
63    }
64
65    /// Sends the transaction.
66    pub fn send(self) -> Result<(), FailedTransactionMetadata> {
67        let token_program_id = self.token_program_id.unwrap_or(&TOKEN_ID);
68        let payer_pk = self.payer.pubkey();
69
70        let authority = self.owner.unwrap_or(payer_pk);
71        let signing_keys = self.signers.pubkeys();
72        let signer_keys = get_multisig_signers(&authority, &signing_keys);
73
74        let ix = close_account(
75            token_program_id,
76            self.account,
77            self.destination,
78            &authority,
79            &signer_keys,
80        )?;
81
82        super::sign_and_send(self.svm, self.payer, &self.signers, ix)
83    }
84}