Skip to main content

hpsvm_token/
burn_checked.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::{
8    TOKEN_ID, get_multisig_signers, get_spl_account,
9    spl_token::{instruction::burn_checked, state::Mint},
10};
11
12/// ### Description
13/// Builder for the [`burn_checked`] instruction.
14///
15/// ### Optional fields
16/// - `authority`: `payer` by default.
17/// - `decimals`: `mint` decimals by default.
18/// - `token_program_id`: [`TOKEN_ID`] by default.
19#[derive(Debug)]
20pub struct BurnChecked<'a> {
21    svm: &'a mut HPSVM,
22    payer: &'a Keypair,
23    mint: &'a Address,
24    account: &'a Address,
25    token_program_id: Option<&'a Address>,
26    amount: u64,
27    decimals: Option<u8>,
28    signers: SmallVec<[&'a Keypair; 1]>,
29    owner: Option<Address>,
30}
31
32impl<'a> BurnChecked<'a> {
33    /// Creates a new instance of [`burn_checked`] instruction.
34    pub fn new(
35        svm: &'a mut HPSVM,
36        payer: &'a Keypair,
37        mint: &'a Address,
38        account: &'a Address,
39        amount: u64,
40    ) -> Self {
41        BurnChecked {
42            svm,
43            payer,
44            mint,
45            account,
46            token_program_id: None,
47            amount,
48            decimals: None,
49            owner: None,
50            signers: smallvec![payer],
51        }
52    }
53
54    /// Sets the token program id of the burn.
55    pub fn token_program_id(mut self, program_id: &'a Address) -> Self {
56        self.token_program_id = Some(program_id);
57        self
58    }
59
60    /// Sets the decimals of the burn.
61    pub fn decimals(mut self, value: u8) -> Self {
62        self.decimals = Some(value);
63        self
64    }
65
66    /// Sets the owner of the account with single owner.
67    pub fn owner(mut self, owner: &'a Keypair) -> Self {
68        self.owner = Some(owner.pubkey());
69        self.signers = smallvec![owner];
70        self
71    }
72
73    /// Sets the owner of the account with multisig owner.
74    pub fn multisig(mut self, multisig: &'a Address, signers: &'a [&'a Keypair]) -> Self {
75        self.owner = Some(*multisig);
76        self.signers = SmallVec::from(signers);
77        self
78    }
79
80    /// Sends the transaction.
81    pub fn send(self) -> Result<(), FailedTransactionMetadata> {
82        let payer_pk = self.payer.pubkey();
83        let token_program_id = self.token_program_id.unwrap_or(&TOKEN_ID);
84
85        let authority = self.owner.unwrap_or(payer_pk);
86        let signing_keys = self.signers.pubkeys();
87        let signer_keys = get_multisig_signers(&authority, &signing_keys);
88
89        let mint: Mint = get_spl_account(self.svm, self.mint)?;
90        let ix = burn_checked(
91            token_program_id,
92            self.account,
93            self.mint,
94            &authority,
95            &signer_keys,
96            self.amount,
97            self.decimals.unwrap_or(mint.decimals),
98        )?;
99
100        super::sign_and_send(self.svm, self.payer, &self.signers, ix)
101    }
102}