> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Programmatic Solana Staking with Helius SDK

> Build seamless Solana staking experiences with the Helius SDK. Complete guide from setup to withdrawal with 0% commission validator integration.

> [!NOTE]
>
> **Zero-Commission Validator**: Stake with the Helius validator and keep 100% of your staking rewards with our 0% commission rate.

## Quick Overview

The Helius SDK provides simple methods to handle the complete SOL staking lifecycle programmatically. Perfect for building staking interfaces, DeFi protocols, or automated staking strategies.

> [card] Create & Delegate
>
> Set up new stake accounts and delegate to validators in one transaction

> [card] Monitor & Manage
>
> Track rewards, check status, and manage existing stake accounts

> [card] Withdraw & Redeem
>
> Deactivate stakes and withdraw SOL after cooldown periods

## Installation & Setup

```bash npm theme={"system"}
npm install helius-sdk @solana/web3.js bs58
```

```bash yarn   theme={"system"}
yarn add helius-sdk @solana/web3.js bs58
```

```bash pnpm theme={"system"}
pnpm add helius-sdk @solana/web3.js bs58
```

```typescript Setup theme={"system"}
import { Helius } from 'helius-sdk';
import { Keypair, Transaction } from '@solana/web3.js';
import bs58 from 'bs58';

// Initialize Helius client
const helius = new Helius('YOUR_API_KEY');

// Your wallet keypair (load from your secure storage)
const payer = Keypair.fromSecretKey(/* your secret key */);
```

## Staking Basics

> [accordion] How Solana Staking Works
>
> **Stake Account**: A special account that locks SOL and delegates it to a validator. Each stake account points to exactly one validator.
>
> **Rewards**: Validators earn rewards for securing the network. These rewards are distributed to all stake accounts delegated to that validator.
>
> **Lifecycle**: Create → Delegate → Earn Rewards → Deactivate → Withdraw

> [accordion] Why Choose Helius Validator
>
> * **0% Commission**: Keep 100% of your staking rewards
> * **High Performance**: Reliable block production and minimal downtime
> * **Easy Integration**: Optimized for the Helius SDK with built-in helpers

> [accordion] Timing & Epochs
>
> * **Activation**: Stakes become active at the start of the next epoch (\~2 days)
> * **Deactivation**: Takes effect at the end of the current epoch
> * **Cooldown**: Deactivated stakes can be withdrawn immediately after epoch end

## Getting Started

> [tab] Quick Start
>
> Stake SOL in just 3 lines of code:
>
> ```typescript theme={"system"}
> // 1. Create the staking transaction
> const { serializedTx, stakeAccountPubkey } = 
>   await helius.rpc.createStakeTransaction(payer.publicKey, 1.5);
>
> // 2. Sign and send
> const tx = Transaction.from(bs58.decode(serializedTx));
> tx.partialSign(payer);
> const signature = await helius.connection.sendRawTransaction(tx.serialize());
>
> console.log(`Staked! Transaction: ${signature}`);
> console.log(`Stake Account: ${stakeAccountPubkey}`);
> ```
>
> > [!NOTE]
> >
> > The SDK automatically handles rent calculation and stake account creation. The `1.5` parameter is the amount in SOL you want to stake.

> [tab] Complete Example
>
> Full staking implementation with error handling:
>
> ```typescript theme={"system"}
> async function stakeSOL(amountInSol: number) {
>   try {
>     // Create staking transaction
>     const { serializedTx, stakeAccountPubkey } = 
>       await helius.rpc.createStakeTransaction(payer.publicKey, amountInSol);
>
>     // Deserialize and sign transaction
>     const transaction = Transaction.from(bs58.decode(serializedTx));
>     transaction.partialSign(payer);
>
>     // Send transaction
>     const signature = await helius.connection.sendRawTransaction(
>       transaction.serialize(),
>       { 
>         skipPreflight: false,
>         preflightCommitment: 'confirmed'
>       }
>     );
>
>     // Wait for confirmation
>     await helius.connection.confirmTransaction(signature, 'confirmed');
>
>     return {
>       signature,
>       stakeAccount: stakeAccountPubkey,
>       amount: amountInSol
>     };
>
>   } catch (error) {
>     console.error('Staking failed:', error);
>     throw error;
>   }
> }
>
> // Usage
> const result = await stakeSOL(2.5);
> console.log(`Successfully staked ${result.amount} SOL`);
> ```

## SDK Methods Reference

> [accordion] createStakeTransaction(owner, amount)
>
> Creates a complete staking transaction that can be signed and sent.
>
> **Parameters:**
>
> * `owner` (PublicKey): The wallet that will own the stake account
> * `amount` (number): Amount of SOL to stake
>
> **Returns:**
>
> ```typescript theme={"system"}
> {
>   serializedTx: string,        // Base58 encoded transaction
>   stakeAccountPubkey: string   // New stake account address
> }
> ```
>
> **Example:**
>
> ```typescript theme={"system"}
> const result = await helius.rpc.createStakeTransaction(
>   payer.publicKey, 
>   1.5  // 1.5 SOL
> );
> ```

> [accordion] getStakeInstructions(owner, amount)
>
> Returns just the instructions for staking (useful for custom transaction building).
>
> **Returns:**
>
> ```typescript theme={"system"}
> {
>   instructions: TransactionInstruction[],
>   stakeAccount: Keypair
> }
> ```
>
> **Example:**
>
> ```typescript theme={"system"}
> const { instructions } = await helius.rpc.getStakeInstructions(
>   payer.publicKey, 
>   1.5
> );
>
> // Use with Smart Transactions
> const signature = await helius.rpc.sendSmartTransaction(
>   instructions, 
>   [payer]
> );
> ```

> [accordion] getHeliusStakeAccounts(wallet)
>
> Retrieves all stake accounts delegated to the Helius validator for a wallet.
>
> **Example:**
>
> ```typescript theme={"system"}
> const accounts = await helius.rpc.getHeliusStakeAccounts(
>   payer.publicKey.toBase58()
> );
>
> accounts.forEach(account => {
>   const delegation = account.account.data.parsed.info.stake.delegation;
>   console.log(`Account: ${account.pubkey}`);
>   console.log(`Stake: ${delegation.stake / LAMPORTS_PER_SOL} SOL`);
> });
> ```

> [accordion] createUnstakeTransaction(owner, stakeAccount)
>
> Creates a transaction to deactivate (begin unstaking) a stake account.
>
> **Example:**
>
> ```typescript theme={"system"}
> const tx = await helius.rpc.createUnstakeTransaction(
>   payer.publicKey,
>   stakeAccountPubkey
> );
>
> const transaction = Transaction.from(bs58.decode(tx));
> transaction.partialSign(payer);
> await helius.connection.sendRawTransaction(transaction.serialize());
> ```

> [accordion] getWithdrawableAmount(stakeAccount, includeRent?)
>
> Check how much SOL can be withdrawn from a deactivated stake account.
>
> **Parameters:**
>
> * `includeRent` (boolean): Whether to include rent-exempt amount
>
> **Example:**
>
> ```typescript theme={"system"}
> const available = await helius.rpc.getWithdrawableAmount(stakeAccountPubkey);
> const total = await helius.rpc.getWithdrawableAmount(stakeAccountPubkey, true);
>
> console.log(`Available now: ${available / LAMPORTS_PER_SOL} SOL`);
> console.log(`Total balance: ${total / LAMPORTS_PER_SOL} SOL`);
> ```

> [accordion] createWithdrawTransaction(owner, stakeAccount, destination, amount)
>
> Creates a transaction to withdraw SOL from a deactivated stake account.
>
> **Example:**
>
> ```typescript theme={"system"}
> const tx = await helius.rpc.createWithdrawTransaction(
>   payer.publicKey,
>   stakeAccountPubkey,
>   destinationPubkey,
>   withdrawAmount  // in lamports
> );
> ```

## Complete Staking Workflow

**1. Create and Delegate**

```typescript theme={"system"}
// Stake 2 SOL to Helius validator
const { serializedTx, stakeAccountPubkey } = 
  await helius.rpc.createStakeTransaction(payer.publicKey, 2.0);

const tx = Transaction.from(bs58.decode(serializedTx));
tx.partialSign(payer);

const signature = await helius.connection.sendRawTransaction(tx.serialize());
console.log(`Stake created: ${stakeAccountPubkey}`);
```

**2. Monitor Your Stakes**

```typescript theme={"system"}
// Get all your Helius stake accounts
const accounts = await helius.rpc.getHeliusStakeAccounts(
  payer.publicKey.toBase58()
);

console.log(`You have ${accounts.length} active stake accounts`);

accounts.forEach((account, index) => {
  const info = account.account.data.parsed.info;
  const delegation = info.stake.delegation;
  
  console.log(`Stake ${index + 1}:`);
  console.log(`  Amount: ${delegation.stake / LAMPORTS_PER_SOL} SOL`);
  console.log(`  Activated: Epoch ${delegation.activationEpoch}`);
  console.log(`  Status: ${info.meta.lockup.unixTimestamp === 0 ? 'Active' : 'Locked'}`);
});
```

**3. Deactivate (Start Unstaking)**

```typescript theme={"system"}
// Begin the unstaking process
const unstakeTx = await helius.rpc.createUnstakeTransaction(
  payer.publicKey,
  stakeAccountPubkey
);

const tx = Transaction.from(bs58.decode(unstakeTx));
tx.partialSign(payer);

await helius.connection.sendRawTransaction(tx.serialize());
console.log('Deactivation started. Will be withdrawable next epoch.');
```

**4. Withdraw SOL**

```typescript theme={"system"}
// Check withdrawable amount
const withdrawable = await helius.rpc.getWithdrawableAmount(
  stakeAccountPubkey, 
  true  // include rent
);

if (withdrawable > 0) {
  // Create withdrawal instruction
  const withdrawInstruction = helius.rpc.getWithdrawInstruction(
    payer.publicKey,
    stakeAccountPubkey,
    payer.publicKey,  // withdraw to same wallet
    withdrawable
  );
  
  // Send using Smart Transactions for better reliability
  const signature = await helius.rpc.sendSmartTransaction(
    [withdrawInstruction], 
    [payer]
  );
  
  console.log(`Withdrawn ${withdrawable / LAMPORTS_PER_SOL} SOL`);
}
```

## Advanced Patterns

> [tab] Browser Integration
>
> For browser applications using wallet adapters:
>
> ```typescript theme={"system"}
> // Get instructions instead of full transaction
> const { instructions, stakeAccount } = await helius.rpc.getStakeInstructions(
>   wallet.publicKey,
>   stakeAmount
> );
>
> // Let the wallet handle transaction building and signing
> const transaction = new Transaction().add(...instructions);
>
> // Sign with wallet adapter
> const signature = await wallet.sendTransaction(transaction, connection);
>
> console.log(`Stake account: ${stakeAccount.publicKey.toBase58()}`);
> ```

> [tab] Batch Operations
>
> Stake for multiple wallets efficiently:
>
> ```typescript theme={"system"}
> async function batchStake(wallets: Keypair[], amount: number) {
>   const promises = wallets.map(async (wallet) => {
>     try {
>       const { serializedTx, stakeAccountPubkey } = 
>         await helius.rpc.createStakeTransaction(wallet.publicKey, amount);
>
>       const tx = Transaction.from(bs58.decode(serializedTx));
>       tx.partialSign(wallet);
>
>       return helius.connection.sendRawTransaction(tx.serialize());
>     } catch (error) {
>       console.error(`Failed to stake for ${wallet.publicKey.toBase58()}:`, error);
>       return null;
>     }
>   });
>
>   const results = await Promise.allSettled(promises);
>   const successful = results.filter(r => r.status === 'fulfilled').length;
>
>   console.log(`Successfully staked for ${successful}/${wallets.length} wallets`);
> }
> ```

> [tab] Smart Transactions
>
> Use Smart Transactions for better reliability and optimization:
>
> ```typescript theme={"system"}
> // Get individual instructions
> const { instructions } = await helius.rpc.getStakeInstructions(
>   payer.publicKey,
>   2.5
> );
>
> // Send with Smart Transaction features:
> // - Automatic priority fee optimization
> // - Retry logic with backoff
> // - Better error handling
> const signature = await helius.rpc.sendSmartTransaction(
>   instructions,
>   [payer],
>   {
>     skipPreflight: false,
>     maxRetries: 3
>   }
> );
>
> console.log(`Smart transaction sent: ${signature}`);
> ```

## Important Notes

> [!WARNING]
>
> **Epoch Timing**: Solana epochs last \~2 days. Stakes activate at the next epoch start, and deactivation takes effect at the current epoch end.

> [!NOTE]
>
> **Rent Considerations**: Stake accounts need rent-exempt reserves (\~0.00228 SOL). Withdrawing the full balance closes the account.

> [!TIP]
>
> **Hardware Wallets**: Users will see two signature prompts - one for the stake account (pre-signed) and one for the fee payer. Design your UX accordingly.

## Quick Reference

Need a quick reminder? Here are the essential methods:

```typescript theme={"system"}
// Stake SOL
await helius.rpc.createStakeTransaction(owner, amountInSol);

// Check your stakes  
await helius.rpc.getHeliusStakeAccounts(ownerAddress);

// Start unstaking
await helius.rpc.createUnstakeTransaction(owner, stakeAccount);

// Check withdrawable amount
await helius.rpc.getWithdrawableAmount(stakeAccount, includeRent);

// Withdraw SOL
helius.rpc.getWithdrawInstruction(owner, stakeAccount, destination, amount);
```

## Next Steps

> [card] [Helius SDK Documentation](https://github.com/helius-labs/helius-sdk)
>
> Complete SDK reference with all available methods

> [card] [Smart Transactions](https://www.helius.dev/docs/sending-transactions/optimizing-transactions.md)
>
> Optimize your transactions with priority fees and retry logic

> [card] [Join Discord](https://discord.com/invite/6GXdee3gBj)
>
> Get help from our developer community

> [card] [Validator Dashboard](https://www.validators.app/validators/EKgWgpJY5BtX7TeJfhKbqcJT7gzLKFFtj7cjX1XY6CxA)
>
> Monitor Helius validator performance and rewards


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.