> For the complete documentation index, see [llms.txt](https://wiki.solaxy.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.solaxy.io/using-custom-code/transferring-sol.md).

# Transferring SOL

* Creating an Account

  <pre class="language-rust" data-overflow="wrap"><code class="lang-rust">use std::time::Duration;

  use anyhow::anyhow;
  use jsonrpsee::tracing::debug;
  use solana_program::system_program;
  use solana_sdk::{
      account::Account,
      signature::{Keypair, Signer},
  };
  use tokio::time::sleep;

  use crate::{client::TestClient, SLEEP_DURATION_SECONDS};

  /// Prepares a Solana transaction for a create_account instruction.
  /// Returns a base58-encoded string representation of the prepared transaction.
  pub fn prepare_new_account_transaction(
      payer: &#x26;Keypair,
      new_account: &#x26;Keypair,
      rent: u64,
      blockhash: Hash,
  ) -> Transaction {
      let instruction = system_instruction::create_account(
          &#x26;payer.pubkey(),
          &#x26;new_account.pubkey(),
          rent,
          0,
          &#x26;system_program::id(),
      );

      Transaction::new_signed_with_payer(
          &#x26;[instruction],
          Some(&#x26;payer.pubkey()),
          &#x26;[payer, new_account],
          blockhash,
      )
  }

  pub(crate) async fn create_account(
      client: &#x26;TestClient,
      payer: &#x26;Keypair,
      new_account: &#x26;Keypair,
      amount: u64,
  ) -> anyhow::Result&#x3C;()> {
      debug!("Create new account");
      // Get initial balance
      let payer_initial_balance = client
          .svm_get_account_balance(payer.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get payer's initial balance: {e}"))?;

      // Get latest blockhash
      let latest_blockhash = client
          .svm_get_latest_blockhash()
          .await
          .map_err(|e| anyhow!("Failed to retrieve the latest blockhash: {e}"))?;

      let create_acc_tx =
          prepare_new_account_transaction(payer, new_account, amount, latest_blockhash);

      let total_gas_fee_estimate = client
          .get_total_fee_for_transaction(&#x26;create_acc_tx)
          .await
          .map_err(|e| anyhow!("Failed to get total fee estimate for transaction: {e}"))?;

      let tx_hash = client
          .svm_send_transaction(&#x26;create_acc_tx)
          .await
          .map_err(|e| anyhow!("Failed to send a transaction: {e}"))?
          .to_string();

      // Wait for transactions to process and persist changes
      sleep(Duration::from_secs(SLEEP_DURATION_SECONDS)).await;

      // Check accounts and balances
      // Check payer's post balance
      let payer_post_balance = client
          .svm_get_account_balance(payer.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get payer's post balance: {e}"))?;
      let expected_balance = payer_initial_balance - amount - total_gas_fee_estimate;

      // Check new account's post balance
      let new_acc_balance = client
          .svm_get_account_balance(new_account.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get new account's balance: {e}"))?;

      // Check new account's info
      let new_acc_info = client
          .svm_get_account_info(new_account.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to retrieve new account: {e}"))?;
      let new_acc_key = new_account.pubkey();

      Ok(())
  }
  </code></pre>
* Transferring SOL

  <pre class="language-rust" data-overflow="wrap"><code class="lang-rust">/// Prepares a Solana transaction for a transfer instruction.
  /// Returns a base58-encoded string representation of the prepared transaction.
  pub fn prepare_sol_transfer_transaction(
      payer: &#x26;Keypair,
      receiver: &#x26;Pubkey,
      lamports: u64,
      blockhash: Hash,
  ) -> Transaction {
      let instruction = system_instruction::transfer(&#x26;payer.pubkey(), receiver, lamports);
      Transaction::new_signed_with_payer(&#x26;[instruction], Some(&#x26;payer.pubkey()), &#x26;[payer], blockhash)
  }

  pub(crate) async fn transfer_sol(
      client: &#x26;TestClient,
      sender: &#x26;Keypair,
      receiver: &#x26;Keypair,
      amount: u64,
  ) -> anyhow::Result&#x3C;()> {
      // Get initial balances
      let sender_initial_balance = client
          .svm_get_account_balance(sender.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get sender's initial balance: {e}"))?;
      let receiver_initial_balance = client
          .svm_get_account_balance(receiver.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get receiver's initial balance: {e}"))?;

      // Get latest blockhash
      let latest_blockhash = client
          .svm_get_latest_blockhash()
          .await
          .map_err(|e| anyhow!("Failed to retrieve the latest blockhash: {e}"))?;

      // Send and publish transaction
      let sol_transfer_tx =
          prepare_sol_transfer_transaction(sender, &#x26;receiver.pubkey(), amount, latest_blockhash);

      let total_gas_fee_estimate = client
          .get_total_fee_for_transaction(&#x26;sol_transfer_tx)
          .await
          .map_err(|e| anyhow!("Failed to get total fee estimate for transaction: {e}"))?;

      let tx_hash = client
          .svm_send_transaction(&#x26;sol_transfer_tx)
          .await
          .map_err(|e| anyhow!("Failed to send a transaction: {e}"))?
          .to_string();

      // Wait for transactions to process and persist changes
      sleep(Duration::from_secs(SLEEP_DURATION_SECONDS)).await;

      // Check balances post transfer
      // Check sender's post balance
      let sender_post_balance = client
          .svm_get_account_balance(sender.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get sender's post balance: {e}"))?;

      // Check receiver's post balance
      let receiver_post_balance = client
          .svm_get_account_balance(receiver.pubkey())
          .await
          .map_err(|e| anyhow!("Failed to get receiver's post balance: {e}"))?;

      Ok(())
  }
  </code></pre>
