Skip to main content

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