Using the TypeScript SDK

The TypeScript SDK provides a simple interface for interacting with stake pools. This section covers common operations and patterns.

Installation

pnpm add @ignitionfi/spl-stake-pool @solana/web3.js

Or

npm install @ignitionfi/spl-stake-pool @solana/web3.js

Basic Setup

import { Connection, PublicKey, Keypair, clusterApiUrl } from '@solana/web3.js';
import {
  getStakePoolAccount,
  getStakePoolAccounts,
  STAKE_POOL_PROGRAM_ID,
} from '@ignitionfi/spl-stake-pool';

// Connect to cluster
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');

// Load your keypair
const payer = Keypair.fromSecretKey(
  Buffer.from(JSON.parse(process.env.PRIVATE_KEY || '[]'))
);

Finding Stake Pools

// Get all stake pools for a program
const stakePools = await getStakePoolAccounts(
  connection,
  STAKE_POOL_PROGRAM_ID
);

console.log(`Found ${stakePools?.length || 0} stake pools`);

// Get a specific stake pool
const stakePoolAddress = new PublicKey('YOUR_STAKE_POOL_ADDRESS');
const stakePool = await getStakePoolAccount(connection, stakePoolAddress);

console.log('Pool mint:', stakePool.account.data.poolMint.toBase58());
console.log('Total lamports:', stakePool.account.data.totalLamports.toString());

Deposit Operations

Deposit SOL

import { depositSol } from '@ignitionfi/spl-stake-pool';
import { sendAndConfirmTransaction, Transaction } from '@solana/web3.js';

// Deposit 1 SOL into the stake pool
const lamports = 1_000_000_000; // 1 SOL in lamports
const { instructions, signers } = await depositSol(
  connection,
  stakePoolAddress,
  payer.publicKey, // SOL comes from this account
  lamports
);

// Create and send transaction
const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, ...signers],
  { commitment: 'confirmed' }
);

console.log('Deposit successful:', signature);

Deposit Existing Stake Account

import { depositStake } from '@ignitionfi/spl-stake-pool';

// Deposit an existing stake account into the pool
const validatorVoteAccount = new PublicKey('VALIDATOR_VOTE_ADDRESS');
const stakeAccount = new PublicKey('YOUR_STAKE_ACCOUNT');

const { instructions, signers } = await depositStake(
  connection,
  stakePoolAddress,
  payer.publicKey, // Current stake authority
  validatorVoteAccount,
  stakeAccount
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, ...signers]
);

console.log('Stake deposited:', signature);

Withdraw Operations

Withdraw SOL

import { withdrawSol } from '@ignitionfi/spl-stake-pool';

// Withdraw 0.5 pool tokens worth of SOL
const poolTokenAmount = 0.5;
const { instructions, signers } = await withdrawSol(
  connection,
  stakePoolAddress,
  payer.publicKey, // Pool token owner
  payer.publicKey, // SOL receiver
  poolTokenAmount
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, ...signers]
);

console.log('Withdrawal successful:', signature);

Withdraw Stake

import { withdrawStake } from '@ignitionfi/spl-stake-pool';

// Withdraw stake from the pool
const poolTokenAmount = 1.0;
const { instructions, signers, stakeReceiver } = await withdrawStake(
  connection,
  stakePoolAddress,
  payer.publicKey, // Pool token owner
  poolTokenAmount
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, ...signers]
);

console.log('Stake withdrawn to:', stakeReceiver?.toBase58());
console.log('Transaction:', signature);

Session-Based Operations (Gasless Transactions)

The SDK supports session-based operations for gasless transactions using the Fogo Sessions SDK. This is particularly useful for web applications where you want to provide a seamless user experience.

Setup with Fogo Sessions

import { useSession } from '@fogo/sessions-sdk-react';
import {
  depositWsolWithSession,
  withdrawWsolWithSession,
} from '@ignitionfi/spl-stake-pool';

// In your React component
function StakePoolComponent() {
  const { sessionState } = useSession();

  // Session must be established
  if (sessionState.status !== 'established') {
    return <div>Connecting...</div>;
  }

  return <StakeInterface sessionState={sessionState} />;
}

Deposit with Session

import { depositWsolWithSession } from '@ignitionfi/spl-stake-pool';

async function depositWithSession(
  connection,
  stakePoolAddress,
  sessionState,
  amount
) {
  const lamports = amount * 1_000_000_000; // Convert SOL to lamports

  // Create deposit instructions using session
  const { instructions } = await depositWsolWithSession(
    connection,
    stakePoolAddress,
    sessionState.sessionPublicKey, // Session signer
    sessionState.walletPublicKey, // User's wallet
    lamports,
    undefined, // destinationTokenAccount (auto-created)
    undefined, // referrerTokenAccount (optional)
    undefined, // depositAuthority (optional)
    sessionState.payer // Session payer
  );

  // Send using session
  const result = await sessionState.sendTransaction(instructions);

  console.log('Signature:', result.signature);
  return result;
}

Withdraw with Session

import { withdrawWsolWithSession } from '@ignitionfi/spl-stake-pool';

async function withdrawWithSession(
  connection,
  stakePoolAddress,
  sessionState,
  poolTokenAmount
) {
  // Create withdraw instructions using session
  const { instructions } = await withdrawWsolWithSession(
    connection,
    stakePoolAddress,
    sessionState.sessionPublicKey, // Session signer
    sessionState.walletPublicKey, // User's wallet
    poolTokenAmount
  );

  // Send using session
  const result = await sessionState.sendTransaction(instructions);

  console.log('Signature:', result.signature);
  return result;
}

Validator Management Operations

Add Validator to Pool

import { addValidatorToPool } from '@ignitionfi/spl-stake-pool';

const validatorVoteAccount = new PublicKey('VALIDATOR_VOTE_ADDRESS');

const { instructions } = await addValidatorToPool(
  connection,
  stakePoolAddress,
  validatorVoteAccount
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer] // Must be pool staker
);

console.log('Validator added:', signature);

Remove Validator from Pool

import { removeValidatorFromPool } from '@ignitionfi/spl-stake-pool';

const { instructions } = await removeValidatorFromPool(
  connection,
  stakePoolAddress,
  validatorVoteAccount
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer] // Must be pool staker
);

console.log('Validator removed:', signature);

Increase Validator Stake

import { increaseValidatorStake } from '@ignitionfi/spl-stake-pool';

const lamports = 5_000_000_000; // 5 SOL to add to validator

const { instructions } = await increaseValidatorStake(
  connection,
  stakePoolAddress,
  validatorVoteAccount,
  lamports
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer] // Must be pool staker
);

console.log('Validator stake increased:', signature);

Decrease Validator Stake

import { decreaseValidatorStake } from '@ignitionfi/spl-stake-pool';

const lamports = 2_000_000_000; // 2 SOL to remove from validator

const { instructions } = await decreaseValidatorStake(
  connection,
  stakePoolAddress,
  validatorVoteAccount,
  lamports
);

const transaction = new Transaction().add(...instructions);
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer] // Must be pool staker
);

console.log('Validator stake decreased:', signature);

Pool Maintenance and Information

Update Stake Pool

import { updateStakePool } from '@ignitionfi/spl-stake-pool';

// Update pool after epoch change
const stakePool = await getStakePoolAccount(connection, stakePoolAddress);

const { updateListInstructions, finalInstructions } = await updateStakePool(
  connection,
  stakePool,
  false // noMerge flag
);

// Send update list instructions first (may need multiple transactions)
for (const instruction of updateListInstructions) {
  const tx = new Transaction().add(instruction);
  await sendAndConfirmTransaction(connection, tx, [payer]);
}

// Send final instructions
const finalTx = new Transaction().add(...finalInstructions);
await sendAndConfirmTransaction(connection, finalTx, [payer]);

console.log('Stake pool updated');

Get Stake Pool Information

import { stakePoolInfo } from '@ignitionfi/spl-stake-pool';

// Get comprehensive pool information
const info = await stakePoolInfo(connection, stakePoolAddress);

console.log('Pool address:', info.address);
console.log('Manager:', info.manager);
console.log('Total lamports:', info.totalLamports);
console.log('Pool token supply:', info.poolTokenSupply);
console.log('Current validators:', info.details.currentNumberOfValidators);
console.log('Max validators:', info.details.maxNumberOfValidators);
console.log('Update required:', info.details.updateRequired);

// List all validators
info.validatorList.forEach((validator, index) => {
  console.log(`Validator ${index + 1}:`, validator.voteAccountAddress);
  console.log('  Active stake:', validator.activeStakeLamports);
  console.log('  Transient stake:', validator.transientStakeLamports);
});

Last updated