use light_client::rpc::{Rpc, RpcError};
use light_token::instruction::Approve as ApproveInstruction;
use solana_keypair::Keypair;
use solana_pubkey::Pubkey;
use solana_signature::Signature;
use solana_signer::Signer;
#[derive(Default, Clone, Debug)]
pub struct Approve {
pub token_account: Pubkey,
pub delegate: Pubkey,
pub amount: u64,
pub owner: Option<Pubkey>,
}
impl Approve {
pub async fn execute<R: Rpc>(
self,
rpc: &mut R,
payer: &Keypair,
) -> Result<Signature, RpcError> {
let owner_pubkey = self.owner.unwrap_or_else(|| payer.pubkey());
if owner_pubkey != payer.pubkey() {
return Err(RpcError::CustomError(
"owner does not match payer; use execute_with_owner for separate owner/payer"
.to_string(),
));
}
let ix = ApproveInstruction {
token_account: self.token_account,
delegate: self.delegate,
owner: owner_pubkey,
amount: self.amount,
fee_payer: payer.pubkey(),
}
.instruction()
.map_err(|e| RpcError::CustomError(format!("Failed to create instruction: {}", e)))?;
rpc.create_and_send_transaction(&[ix], &payer.pubkey(), &[payer])
.await
}
pub async fn execute_with_owner<R: Rpc>(
self,
rpc: &mut R,
payer: &Keypair,
owner: &Keypair,
) -> Result<Signature, RpcError> {
if let Some(expected_owner) = self.owner {
if expected_owner != owner.pubkey() {
return Err(RpcError::CustomError(format!(
"owner mismatch: self.owner ({}) does not match owner.pubkey() ({})",
expected_owner,
owner.pubkey()
)));
}
}
let ix = ApproveInstruction {
token_account: self.token_account,
delegate: self.delegate,
owner: owner.pubkey(),
amount: self.amount,
fee_payer: payer.pubkey(),
}
.instruction()
.map_err(|e| RpcError::CustomError(format!("Failed to create instruction: {}", e)))?;
let mut signers: Vec<&Keypair> = vec![payer];
if owner.pubkey() != payer.pubkey() {
signers.push(owner);
}
rpc.create_and_send_transaction(&[ix], &payer.pubkey(), &signers)
.await
}
}