1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
use std::ops::{Deref, DerefMut}; pub use solana_client::{client_error, rpc_client::RpcClient}; use solana_sdk::{ hash::Hash, program_error::ProgramError, pubkey::Pubkey, signature::{Keypair, Signature, Signer}, system_instruction, transaction::Transaction, }; use thiserror::Error; #[derive(Debug, Error)] pub enum ClientError { #[error(transparent)] Client(#[from] client_error::ClientError), #[error(transparent)] Program(#[from] ProgramError), } pub type ClientResult<T> = Result<T, ClientError>; pub struct Client { pub client: RpcClient, pub payer: Keypair, } impl Client { pub fn payer(&self) -> &Keypair { &self.payer } pub fn payer_pubkey(&self) -> Pubkey { self.payer.pubkey() } pub fn recent_blockhash(&self) -> ClientResult<Hash> { Ok(self.client.get_recent_blockhash()?.0) } pub fn process_transaction(&self, transaction: &Transaction) -> ClientResult<()> { self.send_and_confirm_transaction(transaction)?; Ok(()) } pub fn create_account( &self, owner: &Pubkey, account_data_len: usize, lamports: Option<u64>, ) -> ClientResult<Keypair> { let account = Keypair::new(); let lamports = if let Some(lamports) = lamports { lamports } else { self.get_minimum_balance_for_rent_exemption(account_data_len)? }; let mut transaction = Transaction::new_with_payer( &[system_instruction::create_account( &self.payer_pubkey(), &account.pubkey(), lamports, account_data_len as u64, owner, )], Some(&self.payer_pubkey()), ); transaction.sign(&[self.payer(), &account], self.recent_blockhash()?); self.process_transaction(&transaction)?; Ok(account) } pub fn airdrop(&self, to_pubkey: &Pubkey, lamports: u64) -> ClientResult<Signature> { let (blockhash, _fee_calculator) = self.client.get_recent_blockhash()?; let signature = self.request_airdrop_with_blockhash(to_pubkey, lamports, &blockhash)?; self.confirm_transaction_with_spinner(&signature, &blockhash, self.commitment())?; Ok(signature) } } impl Deref for Client { type Target = RpcClient; fn deref(&self) -> &Self::Target { &self.client } } impl DerefMut for Client { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.client } }