This Rust script facilitates transferring SOL (Solana) from your wallet to a specified recipient address. It utilizes the Solana RPC client to interact with the Solana blockchain and execute a SOL transfer transaction.
Solana Wallet Topping Script
This Rust script facilitates transferring SOL (Solana) from your wallet to a specified recipient address. It utilizes the Solana RPC client to interact with the Solana blockchain and execute a SOL transfer transaction.
Features
- Dynamic Keypair Loading: Automatically locates and loads the keypair file.
- Balance Check: Displays the sender's balance before proceeding with the transaction.
- Configurable Transfer Amount: Easily adjust the amount to be transferred.
- Error Handling: Comprehensive error handling for robust operation.
- Transaction Confirmation: Verifies and prints the transaction signature upon success.
Prerequisites
Ensure the following are installed on your system:
- Rust (with
cargofor package management) - Solana CLI tools
- A Solana wallet with sufficient funds
Setup Instructions
Environment Variables
Set the SOLANA_KEYPAIR environment variable to point to your Solana wallet's keypair file. If this variable is not set, the script defaults to looking for the keypair file at ~/.config/solana/id.json.
Example
export SOLANA_KEYPAIR=path/to/your/id.json
Configuring the Script
Modify the following variables within the script to suit your requirements:
- Recipient Address: The Solana address to which the SOL will be sent.
- Transfer Amount: The amount of SOL to transfer (specified in lamports).
Script Code
use solanaclient::rpcclient::RpcClient;
use solana_sdk::{
signature::{Keypair, Signer},
transaction::Transaction,
system_instruction,
pubkey::Pubkey,
message::Message,
};
use std::str::FromStr;
use std::fs::File;
use std::io::Read;
use serde_json::Value;
use dirs::home_dir;
fn main() { // Define the recipient address let recipient_address = "9VsY3Q9cPPiFf9984XJFXG7UEYdAUWpD1wuycvowprDm";
// Load the keypair let keypairpath = std::env::var("SOLANAKEYPAIR").unwraporelse(|_| { let mut homedir = homedir().expect("Unable to find home directory"); home_dir.push(".config/solana/id.json"); homedir.tostringlossy().tostring() });
let keypairfile = File::open(&keypairpath).expect("Unable to open keypair file"); let keypairdata: Value = serdejson::fromreader(keypairfile).expect("Unable to parse keypair file"); let keypairbytes: Vec<u8> = keypairdata.as_array() .expect("Expected array") .iter() .map(|v| v.as_u64().expect("Expected integer") as u8) .collect(); let senderkeypair = Keypair::frombytes(&keypair_bytes).expect("Invalid keypair bytes");
println!("Sender pubkey: {}", sender_keypair.pubkey());
// Create an RPC client let rpc_client = RpcClient::new("http://127.0.0.1:8899");
// Get and print the sender's balance let senderbalance = rpcclient.getbalance(&senderkeypair.pubkey()) .expect("Failed to get sender balance");
println!("Sender balance: {} lamports", sender_balance);
// Define the amount to transfer let transferamount = 10000000000; // 10 SOL = 10000000_000 lamports
// Check if the sender has sufficient balance if senderbalance < transferamount { eprintln!("Insufficient balance to perform the transfer"); return; }
// Get the recipient public key let recipientpubkey = Pubkey::fromstr(recipient_address).expect("Invalid recipient address");
// Get a new blockhash for the transfer transaction let recentblockhash = rpcclient.getlatestblockhash().expect("Failed to get latest blockhash");
// Create the transfer instruction let transferinstruction = systeminstruction::transfer( &sender_keypair.pubkey(), &recipient_pubkey, transfer_amount, );
// Create the transaction let message = Message::new(&[transferinstruction], Some(&senderkeypair.pubkey())); let transaction = Transaction::new(&[&senderkeypair], message, recentblockhash);
// Send the transaction let signature = match rpcclient.sendandconfirmtransaction(&transaction) { Ok(sig) => sig, Err(err) => { eprintln!("Failed to send transaction: {:?}", err); return; } };
// Print the transaction signature println!("Transaction sent with signature: {}", signature); }
Code Explanation
- Imports: Imports essential modules for interacting with Solana blockchain.
- Define Recipient Address: Specifies the Solana address to receive the SOL.
- Load Keypair: Loads the sender's keypair from a specified file.
- RPC Client: Establishes a connection to the local Solana blockchain.
- Balance Check: Retrieves and prints the sender's balance. Ensures sufficient balance before proceeding.
- Transfer Amount: Specifies the amount of SOL to transfer.
- Create and Send Transaction: Constructs and sends the transaction to the blockchain.
- Transaction Confirmation: Outputs the transaction signature for verification.
Running the Script
To run the script, use the following command:
cargo run
Ensure your Solana RPC server is running locally, or adjust the RPC URL as necessary.
Advanced Configuration
Custom RPC URL
You can modify the RPC URL to connect to a different Solana cluster by changing the RpcClient initialization:
let rpc_client = RpcClient::new("https://api.mainnet-beta.solana.com");
Dynamic Transfer Amount
To dynamically specify the transfer amount, you can read it from an environment variable or a configuration file. Here’s an example of reading from an environment variable:
let transferamount: u64 = std::env::var("TRANSFERAMOUNT")
.expect("TRANSFER_AMOUNT not set")
.parse()
.expect("TRANSFER_AMOUNT must be a number");
Troubleshooting
- Keypair File Not Found: Ensure the keypair file path is correct and the file exists.
- Insufficient Funds: Verify the sender's balance to ensure it has enough SOL.
- Invalid Recipient Address: Confirm that the recipient address is accurate.