litesvm_token/
set_authority.rs

1use {
2    super::{
3        get_multisig_signers,
4        spl_token::instruction::{set_authority, AuthorityType},
5        TOKEN_ID,
6    },
7    litesvm::{types::FailedTransactionMetadata, LiteSVM},
8    smallvec::{smallvec, SmallVec},
9    solana_keypair::Keypair,
10    solana_pubkey::Pubkey,
11    solana_signer::{signers::Signers, Signer},
12    solana_transaction::Transaction,
13};
14
15/// ### Description
16/// Builder for the [`set_authority`] instruction.
17///
18/// ### Optional fields
19/// - `owner`: `payer` by default.
20/// - `token_program_id`: [`TOKEN_ID`] by default.
21pub struct SetAuthority<'a> {
22    svm: &'a mut LiteSVM,
23    payer: &'a Keypair,
24    authority_type: AuthorityType,
25    account: &'a Pubkey,
26    new_authority: Option<&'a Pubkey>,
27    signers: SmallVec<[&'a Keypair; 1]>,
28    owner: Option<Pubkey>,
29    token_program_id: Option<&'a Pubkey>,
30}
31
32impl<'a> SetAuthority<'a> {
33    /// Creates a new instance of [`set_authority`] instruction.
34    pub fn new(
35        svm: &'a mut LiteSVM,
36        payer: &'a Keypair,
37        account: &'a Pubkey,
38        authority_type: AuthorityType,
39    ) -> Self {
40        SetAuthority {
41            svm,
42            payer,
43            owner: None,
44            authority_type,
45            account,
46            new_authority: None,
47            token_program_id: None,
48            signers: smallvec![payer],
49        }
50    }
51
52    /// Sets the owner of the account with single owner.
53    pub fn owner(mut self, owner: &'a Keypair) -> Self {
54        self.owner = Some(owner.pubkey());
55        self.signers = smallvec![owner];
56        self
57    }
58
59    /// Sets the owner of the account with multisig owner.
60    pub fn multisig(mut self, multisig: &'a Pubkey, signers: &'a [&'a Keypair]) -> Self {
61        self.owner = Some(*multisig);
62        self.signers = SmallVec::from(signers);
63        self
64    }
65
66    /// Sets the token program id for the instruction.
67    pub fn token_program_id(mut self, program_id: &'a Pubkey) -> Self {
68        self.token_program_id = Some(program_id);
69        self
70    }
71
72    /// Sets the new authority.
73    pub fn new_authority(mut self, new_authority: &'a Pubkey) -> Self {
74        self.new_authority = Some(new_authority);
75        self
76    }
77
78    /// Sends the transaction.
79    pub fn send(self) -> Result<(), FailedTransactionMetadata> {
80        let token_program_id = self.token_program_id.unwrap_or(&TOKEN_ID);
81        let payer_pk = self.payer.pubkey();
82
83        let authority = self.owner.unwrap_or(payer_pk);
84        let signing_keys = self.signers.pubkeys();
85        let signer_keys = get_multisig_signers(&authority, &signing_keys);
86
87        let ix = set_authority(
88            token_program_id,
89            self.account,
90            self.new_authority,
91            self.authority_type,
92            &authority,
93            &signer_keys,
94        )?;
95
96        let block_hash = self.svm.latest_blockhash();
97        let mut tx = Transaction::new_with_payer(&[ix], Some(&payer_pk));
98        tx.partial_sign(&[self.payer], block_hash);
99        tx.partial_sign(self.signers.as_ref(), block_hash);
100
101        self.svm.send_transaction(tx)?;
102
103        Ok(())
104    }
105}