light_token_client/actions/transfer_checked.rs
1//! Transfer checked action for Light Token.
2//!
3//! This action provides a clean interface for transferring Light Tokens with decimal validation.
4
5use light_client::rpc::{Rpc, RpcError};
6use light_token::instruction::TransferChecked as TransferCheckedInstruction;
7use solana_keypair::Keypair;
8use solana_pubkey::Pubkey;
9use solana_signature::Signature;
10use solana_signer::Signer;
11
12/// Parameters for transferring Light Tokens with decimal validation.
13///
14/// Unlike the basic transfer, this validates the amount against
15/// the token's decimals to ensure the transfer is using the correct precision.
16///
17/// # Example
18/// ```ignore
19/// TransferChecked {
20/// source,
21/// mint,
22/// destination,
23/// amount: 1000,
24/// decimals: 9,
25/// ..Default::default()
26/// }.execute(&mut rpc, &payer, &authority).await?;
27/// ```
28#[derive(Default, Clone, Debug)]
29pub struct TransferChecked {
30 /// Source token account.
31 pub source: Pubkey,
32 /// The mint public key.
33 pub mint: Pubkey,
34 /// Destination token account.
35 pub destination: Pubkey,
36 /// Amount of tokens to transfer.
37 pub amount: u64,
38 /// Expected decimals for the token.
39 pub decimals: u8,
40}
41
42impl TransferChecked {
43 /// Execute the transfer_checked action via RPC.
44 ///
45 /// # Arguments
46 /// * `rpc` - RPC client
47 /// * `payer` - Transaction fee payer keypair (also pays for rent top-ups)
48 /// * `authority` - Authority that can spend from the source account
49 ///
50 /// # Returns
51 /// `Result<Signature, RpcError>` - The transaction signature
52 pub async fn execute<R: Rpc>(
53 self,
54 rpc: &mut R,
55 payer: &Keypair,
56 authority: &Keypair,
57 ) -> Result<Signature, RpcError> {
58 let ix = TransferCheckedInstruction {
59 source: self.source,
60 mint: self.mint,
61 destination: self.destination,
62 amount: self.amount,
63 decimals: self.decimals,
64 authority: authority.pubkey(),
65 fee_payer: payer.pubkey(),
66 }
67 .instruction()
68 .map_err(|e| RpcError::CustomError(format!("Failed to create instruction: {}", e)))?;
69
70 let mut signers = vec![payer];
71 if authority.pubkey() != payer.pubkey() {
72 signers.push(authority);
73 }
74
75 rpc.create_and_send_transaction(&[ix], &payer.pubkey(), &signers)
76 .await
77 }
78}