Complete Sanctum SDK for liquid staking, LST swaps, and Infinity pool operations on Solana. Use when working with LSTs (mSOL, jitoSOL, bSOL, INF), staking SOL, swapping between liquid staking tokens, or integrating Sanctum's liquidity infrastructure.
>_
Quick Install
npxskills add sendaifun/skills--skill sanctum
Instructions
Loading…
Tags & Topics
claude-codeclaude-skillsclaudecodeskillssolana
Sanctum Development Guide
A comprehensive guide for building Solana applications with Sanctum - Solana's largest LST (Liquid Staking Token) platform powering 1,361+ LSTs.
Overview
Sanctum provides unified liquid staking infrastructure on Solana:
Infinity Pool: Multi-LST liquidity pool with zero-slippage swaps
Router: Instant LST-to-LST swaps via stake account routing
Reserve: Instant SOL liquidity for LST withdrawals
LST Creation: Launch custom liquid staking tokens
INF Token: Yield-bearing token representing Infinity pool shares
const SANCTUM_API_BASE = 'https://sanctum-api.ironforge.network';
// All endpoints require API key
const headers = {
'Content-Type': 'application/json',
};
// Example: Get all LST metadata
const response = await fetch(
`${SANCTUM_API_BASE}/lsts?apiKey=${API_KEY}`
);
const lsts = await response.json();
Common LST Addresses
const LST_MINTS = {
// Native SOL (wrapped)
SOL: 'So11111111111111111111111111111111111111112',
// Sanctum INF (Infinity pool token)
INF: '5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm',
// Major LSTs
mSOL: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So', // Marinade
jitoSOL: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn', // Jito
bSOL: 'bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1', // BlazeStake
// Partner LSTs
jupSOL: 'jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v', // Jupiter
bbSOL: 'bbso1MfE7KVL7DhqwZ6dVfKrD3oNV1PEykLNM4kk5dD', // Bybit
dSOL: 'Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ', // Drift
// Other popular LSTs
hSOL: 'he1iusmfkpAdwvxLNGV8Y1iSbj4rUy6yMhEA3fotn9A', // Helius
pwrSOL: 'pWrSoLAhue6jUxUMbWaY8izMhNpWfhiJk7M3Fy3p1Kt', // Power
laineSOL: 'LAinEtNLgpmCP9Rvsf5Hn8W6EhNiKLZQti1xfWMLy6X', // Laine
};
Core Concepts
1. LST (Liquid Staking Token)
LSTs represent staked SOL that remains liquid. When you stake SOL through a stake pool:
You receive LST tokens representing your stake
The stake earns validator rewards
LSTs can be traded, used in DeFi, or swapped back to SOL
2. INF Token
INF is Sanctum's flagship yield-bearing token:
Represents share of Infinity pool's multi-LST holdings
Reward-bearing: Value increases vs SOL (not rebasing)
Earns weighted average of all LST yields + trading fees
No lockups - hold to earn, swap out anytime
// INF increases in value over time
// Example: 1 INF deposited at 1.0 SOL might be worth 1.05 SOL later
const infValue = await getInfSolValue(); // Returns current INF/SOL rate
3. SOL Value Calculators
On-chain programs that convert LST amounts to intrinsic SOL value:
// Each LST has a dedicated calculator
const SOL_VALUE_CALCULATORS = {
SPL: 'sp1V4h2gWorkGhVcazBc22Hfo2f5sd7jcjT4EDPrWFF',
SanctumSpl: 'sspUE1vrh7xRoXxGsg7vR1zde2WdGtJRbyK9uRumBDy',
SanctumSplMulti: 'ssmbu3KZxgonUtjEMCKspZzxvUQCxAFnyh1rcHUeEDo',
Marinade: 'mare3SCyfZkAndpBRBeonETmkCCB3TJTTrz8ZN2dnhP',
Lido: '1idUSy4MGGKyKhvjSnGZ6Zc7Q4eKQcibym4BkEEw9KR',
wSOL: 'wsoGmxQLSvwWpuaidCApxN5kEowLe2HLQLJhCQnj4bE',
};
API Reference
Base URL
https://sanctum-api.ironforge.network
All endpoints require apiKey query parameter.
Get LST Metadata
// Get all LSTs
GET /lsts?apiKey={key}
// Get specific LST by mint or symbol
GET /lsts/{mintOrSymbol}?apiKey={key}
// Response
interface LstMetadata {
symbol: string;
mint: string;
decimals: number;
tokenProgram: string;
logoUri: string;
name: string;
tvl: number; // Total Value Locked
apy: number; // Current APY
holders: number;
}
// Get swap quote and unsigned transaction
GET /swap/token/order?apiKey={key}&inp={inputMint}&out={outputMint}&amt={amount}&mode={ExactIn|ExactOut}&signer={walletPubkey}&slippageBps={bps}
// Response
interface SwapOrderResponse {
tx: string; // Base64 encoded transaction
inpAmt: string; // Input amount
outAmt: string; // Output amount
source: string; // Swap source (Infinity, Router, etc.)
feeAmt: string; // Fee amount
feeMint: string; // Fee token mint
}
// Execute signed swap
POST /swap/token/execute
Body: {
signedTx: string; // Base64 signed transaction
orderResponse: object; // Original order response
}
// Response
interface SwapExecuteResponse {
txSignature: string;
}
Deposit Stake Account
// Convert native stake account to LST
GET /swap/depositStake/order?apiKey={key}&stakeAccount={pubkey}&outputLstMint={mint}&signer={wallet}
POST /swap/depositStake/execute
Body: {
signedTx: string;
orderResponse: object;
}
Withdraw to Stake Account
// Convert LST back to stake account
GET /swap/withdrawStake/order?apiKey={key}&lstMint={mint}&amount={amount}&signer={wallet}&deactivate={boolean}
POST /swap/withdrawStake/execute
Body: {
signedTx: string;
orderResponse: object;
}
// Get all LST APYs
async function getLstApys(sanctum: SanctumClient): Promise<Map<string, number>> {
const lsts = await sanctum.getLsts();
const apyMap = new Map();
for (const lst of lsts) {
apyMap.set(lst.symbol, lst.apy);
}
return apyMap;
}
// Get specific LST historical APY
async function getLstApyHistory(
sanctum: SanctumClient,
lstMint: string,
limit: number = 30
): Promise<Array<{epoch: number; apy: number}>> {
const response = await fetch(
`${sanctum.baseUrl}/lsts/${lstMint}/apys?apiKey=${sanctum.apiKey}&limit=${limit}`
);
const data = await response.json();
return data.apys;
}
Get TVL
// Get TVL for specific LSTs
async function getTvl(
sanctum: SanctumClient,
symbols: string[]
): Promise<Map<string, number>> {
const tvlMap = new Map();
for (const symbol of symbols) {
const lst = await sanctum.getLst(symbol);
tvlMap.set(symbol, lst.tvl);
}
return tvlMap;
}
Get User Holdings
import { getAccount, getAssociatedTokenAddress } from '@solana/spl-token';
async function getUserLstBalances(
connection: Connection,
wallet: PublicKey,
lstMints: string[]
): Promise<Map<string, bigint>> {
const balances = new Map();
for (const mint of lstMints) {
try {
const ata = await getAssociatedTokenAddress(
new PublicKey(mint),
wallet
);
const account = await getAccount(connection, ata);
balances.set(mint, account.amount);
} catch {
balances.set(mint, 0n);
}
}
return balances;
}