use solana_client::rpc_client::RpcClient;
use solana_commitment_config::CommitmentConfig;
use solana_sdk::{
native_token::LAMPORTS_PER_SOL, pubkey::Pubkey,
signature::Signer,
};
use spherenet_authority::{squads, Authority, ExecutionResult};
use std::str::FromStr;
use solana_system_interface::instruction as system_instruction;
pub fn transfer(
rpc_url: &str,
from: Authority,
destination_str: String,
amount: f64,
) -> eyre::Result<()> {
let rpc_client =
RpcClient::new_with_commitment(rpc_url.to_string(), CommitmentConfig::confirmed());
let destination = Pubkey::from_str(&destination_str).map_err(|e| {
eyre::eyre!(
"Failed to parse destination pubkey {}: {}",
destination_str,
e
)
})?;
let lamports = (amount * LAMPORTS_PER_SOL as f64) as u64;
println!("\nTransferring {} SOL to {}", amount, destination);
match &from {
spherenet_authority::Authority::SingleSig { keypair } => {
println!(" From: {}", keypair.pubkey());
}
spherenet_authority::Authority::MultiSig { multisig, member } => {
println!(" Proposer: {}", member.pubkey());
println!(" Multisig: {}", multisig);
let program_id =
squads::types::SQUADS_PROGRAM_ID.parse::<solana_sdk::pubkey::Pubkey>()?;
let (vault_pda, _) = squads::types::get_vault_pda(multisig, 0, &program_id);
let vault_balance = rpc_client.get_balance(&vault_pda).unwrap_or(0);
let vault_balance_sol = vault_balance as f64 / LAMPORTS_PER_SOL as f64;
println!(" Vault PDA: {}", vault_pda);
println!(" Balance: {:.9} SOL", vault_balance_sol);
}
}
println!();
let from_pubkey = from.instruction_authority_pubkey()?;
let instruction = system_instruction::transfer(&from_pubkey, &destination, lamports);
let description = format!("Transfer {} SOL to {}", amount, destination);
let result = from.execute_instruction(&rpc_client, instruction, &description)?;
if matches!(result, ExecutionResult::Executed { .. }) {
println!("\n✅ Transfer executed successfully!");
}
Ok(())
}