Sending SOL in Python with Solders from a JSON file

So I’ve been struggling with writing a function to transfer all SOL from different wallets in a .json file to a single destination wallet.

Note: The wallets in wallets.json are formatted this way: “index”: 4, “type”: “buy wallet”, “public key”: “7CFFMZ6MDtvBGh996vJEuKiYrgeNBKzgpp2fjHNaZfZ5”, “private key”: “5ioxaWvhwBgbvXEMKs12p8tt8w44yxgsgGVAmi75HXihrh1MeuiusTavsxkD7W4eQEuScoCFQXRfhFKVvz8v8L3d”

My Code:

import cmd
import requests
import os
from solders.keypair import Keypair # type: ignore
from solders.rpc.responses import GetBalanceResp # type: ignore
from solana.rpc.api import Client
from solders.pubkey import Pubkey # type: ignore
from solders.transaction import Transaction # type: ignore
from solders.system_program import TransferParams, transfer
from solders.message import MessageV0 # type: ignore
from solders.commitment_config import CommitmentLevel # type: ignore
from solders.rpc.config import RpcSendTransactionConfig # type: ignore
from art import text2art
import json
import base58
import time

SOLANA_RPC_URL = "https://api.mainnet-beta.solana.com"
client = Client(SOLANA_RPC_URL)

def transfer_sol_to_deposit(filename="wallets.json", deposit_address=None):
    if not deposit_address:
        return "No deposit address provided"
    
    try:
        with open(filename, "r") as f:
            wallets = json.load(f)
            
        deposit_pubkey = Pubkey.from_string(deposit_address)
        client = Client(SOLANA_RPC_URL)
        
        for wallet in wallets:
            try:
                decoded_private = base58.b58decode(wallet['private key'])
                decoded_public = base58.b58decode(wallet['public key'])
                combined = decoded_private[:32] + decoded_public
                wallet_keypair = Keypair.from_bytes(combined)
                wallet_pubkey = Pubkey.from_string(wallet['public key'])
                
                balance_resp = client.get_balance(wallet_pubkey)
                if isinstance(balance_resp, GetBalanceResp):
                    balance_lamports = balance_resp.value
                    if balance_lamports > 5000:
                        transfer_amount = balance_lamports - 5000
                        
                        recent_blockhash = client.get_latest_blockhash().value.blockhash
                        
                        transfer_ix = transfer(TransferParams(
                            from_pubkey=wallet_pubkey,
                            to_pubkey=deposit_pubkey,
                            lamports=transfer_amount
                        ))
                        
                        msg = MessageV0.try_compile(
                            payer=wallet_pubkey,
                            instructions=[transfer_ix],
                            address_lookup_table_accounts=[],
                            recent_blockhash=recent_blockhash
                        )
                        
                        commitment = CommitmentLevel.Confirmed
                        config = RpcSendTransactionConfig(preflight_commitment=commitment)
                        
                        client.send_transaction(msg, wallet_keypair)
                        
                        print(f"Transferred {transfer_amount/1000000000:.9f} SOL from {wallet['public key']}")
                    else:
                        print(f"Insufficient balance in wallet {wallet['public key']}")
                        
            except Exception as e:
                print(f"Error transferring from wallet {wallet['public key']}: {str(e)}")
        
    except FileNotFoundError:
        print("No wallet file found. Please generate wallets first.")
    except json.JSONDecodeError:
        print("Error reading wallet file. File might be corrupted.")
    except Exception as e:
        print(f"An error occurred: {str(e)}")    

Related Articles

Responses

Your email address will not be published. Required fields are marked *