1use solana_client::nonblocking::rpc_client::RpcClient;
2use solana_sdk::pubkey::Pubkey;
3use solana_sdk::signature::Keypair;
4use solana_sdk::signer::Signer;
5use solana_sdk::transaction::Transaction;
6use std::error::Error;
7
8use crate::jito::send_jito_tx;
9
10pub async fn transfer_sol(
11 to: Pubkey,
12 amount: u64,
13 keypair: &Keypair,
14 rpc_client: &RpcClient,
15) -> Result<String, Box<dyn Error>> {
16 let from = keypair.pubkey();
17 let tx = Transaction::new_signed_with_payer(
18 &[solana_sdk::system_instruction::transfer(&from, &to, amount)],
19 None,
20 &[&keypair],
21 rpc_client.get_latest_blockhash().await?,
22 );
23 let res = send_jito_tx(tx).await?;
24
25 Ok(res)
26}
27
28pub async fn transfer_spl(
29 to: Pubkey,
30 amount: u64,
31 mint: Pubkey,
32 keypair: &Keypair,
33 rpc_client: &RpcClient,
34) -> Result<String, Box<dyn Error>> {
35 let from = keypair.pubkey();
36 let from_ata = spl_associated_token_account::get_associated_token_address(
37 &from, &mint,
38 );
39 let to_ata =
40 spl_associated_token_account::get_associated_token_address(&to, &mint);
41
42 let mut instructions = vec![];
43
44 if rpc_client.get_account(&to_ata).await.is_err() {
46 instructions.push(
47 spl_associated_token_account::instruction::create_associated_token_account(
48 &from,
49 &to,
50 &mint,
51 &spl_token::id(),
52 ),
53 );
54 }
55
56 instructions.push(spl_token::instruction::transfer(
57 &spl_token::id(),
58 &from_ata,
59 &to_ata,
60 &from,
61 &[],
62 amount,
63 )?);
64
65 let tx = Transaction::new_signed_with_payer(
66 &instructions,
67 Some(&from),
68 &[keypair],
69 rpc_client.get_latest_blockhash().await?,
70 );
71
72 let res = send_jito_tx(tx).await?;
73
74 Ok(res)
75}
76
77#[cfg(test)]
78mod tests {
79 use solana_sdk::native_token::sol_to_lamports;
80 use solana_sdk::pubkey;
81 use solana_sdk::signer::Signer;
82
83 use super::*;
84 use crate::util::{load_keypair_for_tests, make_rpc_client};
85
86 #[tokio::test]
87 async fn test_transfer_sol() {
88 let keypair = load_keypair_for_tests();
89 let rpc_client = make_rpc_client();
90 let to = keypair.pubkey();
91 let amount = sol_to_lamports(0.0001);
92 let result = transfer_sol(to, amount, &keypair, &rpc_client).await;
93 assert!(result.is_ok());
94 }
95
96 #[tokio::test]
97 async fn test_transfer_spl() {
98 let keypair = load_keypair_for_tests();
99 let rpc_client = make_rpc_client();
100 let to = keypair.pubkey();
101 let mint = pubkey!("Cn5Ne1vmR9ctMGY9z5NC71A3NYFvopjXNyxYtfVYpump");
102 let amount = (1. * 1e6) as u64;
103 let result =
104 transfer_spl(to, amount, mint, &keypair, &rpc_client).await;
105 assert!(result.is_ok());
106 }
107}