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#[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 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 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 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 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 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}