litesvm_token/
transfer.rs1#[cfg_attr(feature = "token-2022", allow(deprecated))]
2use super::{spl_token::instruction::transfer, TOKEN_ID};
3use {
4 super::get_multisig_signers,
5 litesvm::{types::FailedTransactionMetadata, LiteSVM},
6 smallvec::{smallvec, SmallVec},
7 solana_keypair::Keypair,
8 solana_pubkey::Pubkey,
9 solana_signer::{signers::Signers, Signer},
10 solana_transaction::Transaction,
11};
12
13pub struct Transfer<'a> {
21 svm: &'a mut LiteSVM,
22 payer: &'a Keypair,
23 mint: &'a Pubkey,
24 source: Option<&'a Pubkey>,
25 destination: &'a Pubkey,
26 token_program_id: Option<&'a Pubkey>,
27 amount: u64,
28 signers: SmallVec<[&'a Keypair; 1]>,
29 owner: Option<Pubkey>,
30}
31
32impl<'a> Transfer<'a> {
33 pub fn new(
35 svm: &'a mut LiteSVM,
36 payer: &'a Keypair,
37 mint: &'a Pubkey,
38 destination: &'a Pubkey,
39 amount: u64,
40 ) -> Self {
41 Transfer {
42 svm,
43 payer,
44 source: None,
45 destination,
46 token_program_id: None,
47 amount,
48 mint,
49 owner: None,
50 signers: smallvec![payer],
51 }
52 }
53
54 pub fn token_program_id(mut self, program_id: &'a Pubkey) -> Self {
56 self.token_program_id = Some(program_id);
57 self
58 }
59
60 pub fn source(mut self, source: &'a Pubkey) -> Self {
62 self.source = Some(source);
63 self
64 }
65
66 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 pub fn multisig(mut self, multisig: &'a Pubkey, signers: &'a [&'a Keypair]) -> Self {
75 self.owner = Some(*multisig);
76 self.signers = SmallVec::from(signers);
77 self
78 }
79
80 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 source_pk = if let Some(source) = self.source {
90 *source
91 } else {
92 spl_associated_token_account_interface::address::get_associated_token_address_with_program_id(
93 &authority,
94 self.mint,
95 token_program_id,
96 )
97 };
98
99 #[cfg_attr(feature = "token-2022", allow(deprecated))]
100 let ix = transfer(
101 token_program_id,
102 &source_pk,
103 self.destination,
104 &authority,
105 &signer_keys,
106 self.amount,
107 )?;
108
109 let block_hash = self.svm.latest_blockhash();
110 let mut tx = Transaction::new_with_payer(&[ix], Some(&payer_pk));
111 tx.partial_sign(&[self.payer], block_hash);
112 tx.partial_sign(self.signers.as_ref(), block_hash);
113
114 self.svm.send_transaction(tx)?;
115
116 Ok(())
117 }
118}