The Helius SDKs for both Node.js and Rust provide a sendSmartTransaction method that acts as a convenient wrapper around the manual transaction sending process. It can be a great way to get started quickly.

For production applications, we recommend building your own sending logic for maximum control and reliability. The Advanced Guide shows you how to build this yourself, and you can reference the open-source SDK code.

By using sendSmartTransaction, your transaction is automatically routed through our staked connections, giving it a priority lane to the block leader for near-guaranteed delivery.

How sendSmartTransaction Works

Behind the scenes, the SDK performs several critical steps automatically:

1

Fetches Latest Blockhash

Ensures your transaction is built on the most recent network state.

2

Simulates the Transaction

Determines the precise amount of Compute Units (CUs) required.

3

Sets CU Limit

Adds a small buffer to the simulated CUs to prevent execution failures.

4

Gets Priority Fees

Fetches the optimal priority fee from the Helius Priority Fee API.

5

Builds and Sends

Constructs the final, optimized transaction and sends it to the network.

6

Returns Signature

Gives you the transaction ID to track its status.

Node.js SDK Example

Make sure you have the Helius SDK installed (npm install helius-sdk) and updated to at least version 1.3.2 (npm update helius-sdk).

The following example shows how to transfer SOL using sendSmartTransaction.

import { Helius } from "helius-sdk";
import {
  Keypair,
  SystemProgram,
  LAMPORTS_PER_SOL,
  TransactionInstruction,
} from "@solana/web3.js";

// Replace with your Helius API Key
const helius = new Helius("YOUR_API_KEY");

// Create a new keypair to send from
const fromKeypair = Keypair.generate();

// (You'll need to fund this account first)
const fromPubkey = fromKeypair.publicKey;

// The address to send SOL to
const toPubkey = Keypair.generate().publicKey;

// The instruction for the transfer
const instructions: TransactionInstruction[] = [
  SystemProgram.transfer({
    fromPubkey: fromPubkey,
    toPubkey: toPubkey,
    lamports: 0.01 * LAMPORTS_PER_SOL, 
  }),
];

try {
  // Send the transaction
  const transactionSignature = await helius.rpc.sendSmartTransaction(
    instructions, 
    [fromKeypair]
  );

  console.log(`Success! Transaction signature: ${transactionSignature}`);
  console.log(`https://explorer.solana.com/tx/${transactionSignature}?cluster=devnet`);

} catch (e) {
  console.error("Error sending transaction:", e);
}

Rust SDK Example

Make sure you have the Helius Rust SDK crate added to your Cargo.toml and updated to at least version 0.1.5 (cargo update helius).

This example transfers 0.01 SOL and demonstrates how you can pass in additional configuration, such as skipping preflight checks.

use helius::{config::Config, types::*, Helius};
use solana_sdk::{
    pubkey::Pubkey,
    signature::{Keypair, Signer},
    system_instruction,
};
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = env::var("HELIUS_API_KEY").expect("HELIUS_API_KEY must be set");
    let helius = Helius::new(&api_key, Cluster::MainnetBeta)?;

    // Create a new keypair to send from
    let from_keypair = Keypair::new();
    let from_pubkey = from_keypair.pubkey();
    
    // (You'll need to fund this account first)

    // The address to send SOL to
    let to_pubkey = Pubkey::new_unique();

    // Create a simple instruction (transfer 0.01 SOL)
    let lamports = 10_000_000; // 0.01 SOL
    let instruction = system_instruction::transfer(&from_pubkey, &to_pubkey, lamports);

    // Build the config for the smart transaction
    let config = SmartTransactionConfig {
        instructions: vec![instruction],
        signers: vec![&from_keypair],
        ..Default::default()
    };
    
    // Send the transaction
    match helius.send_smart_transaction(&config).await {
        Ok(signature) => {
            println!("✅ Success! Transaction signature: {signature}");
            println!("https://explorer.solana.com/tx/{signature}?cluster=devnet");
        }
        Err(e) => {
            eprintln!("❌ Error sending transaction: {:?}", e);
        }
    }

    Ok(())
}