Skip to content

Instantly share code, notes, and snippets.

@jongan69
Created June 29, 2024 18:21
Show Gist options
  • Save jongan69/9144f95a15e3e47d414d6e97a9d878ba to your computer and use it in GitHub Desktop.
Save jongan69/9144f95a15e3e47d414d6e97a9d878ba to your computer and use it in GitHub Desktop.
lockmaxxing
[package]
name = "juptest"
version = "0.1.0"
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["full"] }
solana-sdk = "1.16"
jupiter-swap-api-client = "0.1.0"
reqwest = "0.11.10" # Use a compatible version of reqwest
serde_json = "1.0"
dotenv = "0.15"
bs58 = "0.5.1"
bincode = "1.3.3"
base64 = "0.22.1"
use base64::Engine;
use dotenv::dotenv;
use jupiter_swap_api_client::{
quote::QuoteRequest, swap::SwapRequest, transaction_config::TransactionConfig,
JupiterSwapApiClient,
};
use reqwest::Client;
use serde_json::json;
use solana_sdk::pubkey::Pubkey;
use solana_sdk::native_token::LAMPORTS_PER_SOL;
use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::transaction::Transaction;
use base64::engine::general_purpose::STANDARD as base64_engine;
use std::str::FromStr;
use bs58;
#[tokio::main]
async fn main() {
dotenv().ok();
let base58privatekey = std::env::var("PRIVATE_KEY").expect("PRIVATE_KEY not set");
let usdc_mint = Pubkey::from_str("8Ki8DpuWNxu9VsS3kQbarsCWMcFGWkzzA8pUPto9zBd5").unwrap();
let native_mint = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap();
let rpc_url = "https://api.mainnet-beta.solana.com";
// Decode the base58 private key
let private_key_bytes = bs58::decode(base58privatekey).into_vec().expect("Invalid base58 string");
let keypair = Keypair::from_bytes(&private_key_bytes).expect("Invalid keypair bytes");
let test_wallet = keypair.pubkey();
// Create HTTP client
let client = Client::new();
// Fetch the balance
let balance_response = client.post(rpc_url)
.json(&json!({
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": [test_wallet.to_string()]
}))
.send()
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();
let sol_balance = balance_response["result"]["value"].as_u64().unwrap();
// Estimate gas fees and rent exemption fees
let gas_fees = 0.001 * LAMPORTS_PER_SOL as f64; // Approximate gas fees
let rent_exemption_fee = 0.004 * LAMPORTS_PER_SOL as f64; // Further increase rent exemption buffer
let total_fees = gas_fees + rent_exemption_fee;
let max_swap_amount = (sol_balance as f64 - total_fees) as u64;
if max_swap_amount <= 0 {
eprintln!("Insufficient balance for swap after accounting for fees. Balance: {} lamports, Total fees: {} lamports", sol_balance, total_fees as u64);
return;
}
println!("SOL Balance: {}", sol_balance);
println!("Estimated Gas Fees: {}", gas_fees as u64);
println!("Estimated Rent Exemption Fees: {}", rent_exemption_fee as u64);
println!("Max Swap Amount: {}", max_swap_amount);
let jupiter_swap_api_client = JupiterSwapApiClient::new("https://quote-api.jup.ag/v6".to_string());
let quote_request = QuoteRequest {
amount: max_swap_amount,
input_mint: native_mint,
output_mint: usdc_mint,
slippage_bps: 50,
..QuoteRequest::default()
};
// GET /quote
let quote_response = jupiter_swap_api_client.quote(&quote_request).await.unwrap();
println!("{quote_response:#?}");
// POST /swap
let swap_response = jupiter_swap_api_client
.swap(&SwapRequest {
user_public_key: test_wallet,
quote_response: quote_response.clone(),
config: TransactionConfig::default(),
})
.await
.unwrap();
println!("Raw tx len: {}", swap_response.swap_transaction.len());
// POST /swap-instructions
let swap_instructions_response = jupiter_swap_api_client
.swap_instructions(&SwapRequest {
user_public_key: test_wallet,
quote_response,
config: TransactionConfig::default(),
})
.await
.unwrap();
println!("{swap_instructions_response:#?}");
// Collect all instructions
let mut instructions = Vec::new();
instructions.extend(swap_instructions_response.setup_instructions);
instructions.push(swap_instructions_response.swap_instruction);
if let Some(cleanup_instruction) = swap_instructions_response.cleanup_instruction {
instructions.push(cleanup_instruction);
}
// Create and sign the transaction
let recent_blockhash = client.post(rpc_url)
.json(&json!({
"jsonrpc": "2.0",
"id": 1,
"method": "getRecentBlockhash",
"params": []
}))
.send()
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap()["result"]["value"]["blockhash"]
.as_str()
.unwrap()
.to_string();
let recent_blockhash = recent_blockhash.parse().unwrap();
let mut transaction = Transaction::new_with_payer(&instructions, Some(&keypair.pubkey()));
transaction.sign(&[&keypair], recent_blockhash);
// Send the transaction
let serialized_transaction = bincode::serialize(&transaction).unwrap();
let base64_transaction = base64_engine.encode(&serialized_transaction);
let send_transaction_response = client.post(rpc_url)
.json(&json!({
"jsonrpc": "2.0",
"id": 1,
"method": "sendTransaction",
"params": [
base64_transaction,
{ "encoding": "base64" }
]
}))
.send()
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();
println!("{send_transaction_response:#?}");
// Check transaction confirmation status
let confirmation_response = client.post(rpc_url)
.json(&json!({
"jsonrpc": "2.0",
"id": 1,
"method": "getTransaction",
"params": [
send_transaction_response["result"].as_str().unwrap(),
{ "encoding": "json" }
]
}))
.send()
.await
.unwrap()
.json::<serde_json::Value>()
.await
.unwrap();
println!("{confirmation_response:#?}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment