sanctum

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Sanctum Development Guide

Sanctum开发指南

A comprehensive guide for building Solana applications with Sanctum - Solana's largest LST (Liquid Staking Token) platform powering 1,361+ LSTs.
这是一份使用Sanctum构建Solana应用的综合指南——Sanctum是Solana最大的LST(流动性质押代币)平台,支持1361种以上的LST。

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
Sanctum在Solana上提供统一的流动性质押基础设施:
  • Infinity池:支持零滑点兑换的多LST流动性池
  • 路由模块:通过质押账户路由实现LST间即时兑换
  • 储备池:为LST赎回提供即时SOL流动性
  • LST创建:发行自定义流动性质押代币
  • INF代币:代表Infinity池份额的生息代币

Key Stats

核心数据

  • 1,361+ LSTs supported
  • $1.4B+ in swap volume facilitated
  • ~8,000 SOL ($1M+) in fees shared with stakers
  • Partners: Jupiter (jupSOL), Bybit (bbSOL), Drift (dSOL), crypto.com (cdcSOL)
  • 支持1361种以上LST
  • 促成超14亿美元的兑换交易量
  • 与质押者共享约8000 SOL(超100万美元)的手续费
  • 合作伙伴:Jupiter(jupSOL)、Bybit(bbSOL)、Drift(dSOL)、crypto.com(cdcSOL)

Quick Start

快速开始

API Setup

API设置

typescript
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();
typescript
const SANCTUM_API_BASE = 'https://sanctum-api.ironforge.network';

// 所有接口均需API密钥
const headers = {
  'Content-Type': 'application/json',
};

// 示例:获取所有LST元数据
const response = await fetch(
  `${SANCTUM_API_BASE}/lsts?apiKey=${API_KEY}`
);
const lsts = await response.json();

Common LST Addresses

常用LST地址

typescript
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
};
typescript
const LST_MINTS = {
  // 原生SOL(包装后)
  SOL: 'So11111111111111111111111111111111111111112',

  // Sanctum INF(Infinity池代币)
  INF: '5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm',

  // 主流LST
  mSOL: 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So',      // Marinade
  jitoSOL: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn', // Jito
  bSOL: 'bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1',      // BlazeStake

  合作伙伴LST
  jupSOL: 'jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v',   // Jupiter
  bbSOL: 'bbso1MfE7KVL7DhqwZ6dVfKrD3oNV1PEykLNM4kk5dD',    // Bybit
  dSOL: 'Dso1bDeDjCQxTrWHqUUi63oBvV7Mdm6WaobLbQ7gnPQ',     // Drift

  // 其他热门LST
  hSOL: 'he1iusmfkpAdwvxLNGV8Y1iSbj4rUy6yMhEA3fotn9A',     // Helius
  pwrSOL: 'pWrSoLAhue6jUxUMbWaY8izMhNpWfhiJk7M3Fy3p1Kt',   // Power
  laineSOL: 'LAinEtNLgpmCP9Rvsf5Hn8W6EhNiKLZQti1xfWMLy6X', // Laine
};

Core Concepts

核心概念

1. LST (Liquid Staking Token)

1. LST(流动性质押代币)

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
LST代表仍具备流动性的质押SOL。当你通过质押池质押SOL时:
  • 你会收到代表质押份额的LST代币
  • 质押会获得验证者奖励
  • LST可进行交易、用于DeFi场景,或兑换回SOL

2. INF Token

2. INF代币

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
typescript
// 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
INF是Sanctum的旗舰生息代币:
  • 代表Infinity池多LST资产的份额
  • 生息特性:相对于SOL的价值会增长(非重基模式)
  • 赚取所有LST收益的加权平均值+交易手续费
  • 无锁仓限制——持有即可获利,随时可兑换退出
typescript
// INF的价值会随时间增长
// 示例:存入1 SOL对应的INF,之后可能价值1.05 SOL
const infValue = await getInfSolValue(); // 返回当前INF/SOL汇率

3. SOL Value Calculators

3. SOL价值计算器

On-chain programs that convert LST amounts to intrinsic SOL value:
typescript
// Each LST has a dedicated calculator
const SOL_VALUE_CALCULATORS = {
  SPL: 'sp1V4h2gWorkGhVcazBc22Hfo2f5sd7jcjT4EDPrWFF',
  SanctumSpl: 'sspUE1vrh7xRoXxGsg7vR1zde2WdGtJRbyK9uRumBDy',
  SanctumSplMulti: 'ssmbu3KZxgonUtjEMCKspZzxvUQCxAFnyh1rcHUeEDo',
  Marinade: 'mare3SCyfZkAndpBRBeonETmkCCB3TJTTrz8ZN2dnhP',
  Lido: '1idUSy4MGGKyKhvjSnGZ6Zc7Q4eKQcibym4BkEEw9KR',
  wSOL: 'wsoGmxQLSvwWpuaidCApxN5kEowLe2HLQLJhCQnj4bE',
};
将LST数量转换为内在SOL价值的链上程序:
typescript
// 每个LST都有对应的计算器
const SOL_VALUE_CALCULATORS = {
  SPL: 'sp1V4h2gWorkGhVcazBc22Hfo2f5sd7jcjT4EDPrWFF',
  SanctumSpl: 'sspUE1vrh7xRoXxGsg7vR1zde2WdGtJRbyK9uRumBDy',
  SanctumSplMulti: 'ssmbu3KZxgonUtjEMCKspZzxvUQCxAFnyh1rcHUeEDo',
  Marinade: 'mare3SCyfZkAndpBRBeonETmkCCB3TJTTrz8ZN2dnhP',
  Lido: '1idUSy4MGGKyKhvjSnGZ6Zc7Q4eKQcibym4BkEEw9KR',
  wSOL: 'wsoGmxQLSvwWpuaidCApxN5kEowLe2HLQLJhCQnj4bE',
};

API Reference

API参考

Base URL

基础URL

https://sanctum-api.ironforge.network
All endpoints require
apiKey
query parameter.
https://sanctum-api.ironforge.network
所有接口均需携带
apiKey
查询参数。

Get LST Metadata

获取LST元数据

typescript
// 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;
}
typescript
// 获取所有LST
GET /lsts?apiKey={key}

// 通过铸币地址或符号获取特定LST
GET /lsts/{mintOrSymbol}?apiKey={key}

// 响应
interface LstMetadata {
  symbol: string;
  mint: string;
  decimals: number;
  tokenProgram: string;
  logoUri: string;
  name: string;
  tvl: number;         // 总锁仓价值
  apy: number;         // 当前年化收益率
  holders: number;
}

Get APY Data

获取APY数据

typescript
// Get validator APYs
GET /validators/apy?apiKey={key}

// Response
interface ValidatorApy {
  [validatorId: string]: {
    avgApy: number;
    timeseries: Array<{epoch: number; apy: number}>;
  };
}

// Get LST historical APYs
GET /lsts/{mintOrSymbol}/apys?apiKey={key}&limit={n}

// Response
interface LstApyHistory {
  apys: Array<{
    epoch: number;
    epochEndTs: number;
    apy: number;
  }>;
}
typescript
// 获取验证者APY
GET /validators/apy?apiKey={key}

// 响应
interface ValidatorApy {
  [validatorId: string]: {
    avgApy: number;
    timeseries: Array<{epoch: number; apy: number}>;
  };
}

// 获取LST历史APY
GET /lsts/{mintOrSymbol}/apys?apiKey={key}&limit={n}

// 响应
interface LstApyHistory {
  apys: Array<{
    epoch: number;
    epochEndTs: number;
    apy: number;
  }>;
}

Swap LSTs

LST兑换

typescript
// 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;
}
typescript
// 获取兑换报价和未签名交易
GET /swap/token/order?apiKey={key}&inp={inputMint}&out={outputMint}&amt={amount}&mode={ExactIn|ExactOut}&signer={walletPubkey}&slippageBps={bps}

// 响应
interface SwapOrderResponse {
  tx: string;           // Base64编码的交易
  inpAmt: string;       // 输入金额
  outAmt: string;       // 输出金额
  source: string;       // 兑换来源(Infinity、路由模块等)
  feeAmt: string;       // 手续费金额
  feeMint: string;      // 手续费代币铸币地址
}

// 执行签名后的兑换
POST /swap/token/execute
请求体: {
  signedTx: string;     // Base64编码的签名交易
  orderResponse: object; // 原始报价响应
}

// 响应
interface SwapExecuteResponse {
  txSignature: string;
}

Deposit Stake Account

存入质押账户

typescript
// 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;
}
typescript
// 将原生质押账户转换为LST
GET /swap/depositStake/order?apiKey={key}&stakeAccount={pubkey}&outputLstMint={mint}&signer={wallet}

POST /swap/depositStake/execute
请求体: {
  signedTx: string;
  orderResponse: object;
}

Withdraw to Stake Account

赎回至质押账户

typescript
// 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;
}
typescript
// 将LST转换回质押账户
GET /swap/withdrawStake/order?apiKey={key}&lstMint={mint}&amount={amount}&signer={wallet}&deactivate={boolean}

POST /swap/withdrawStake/execute
请求体: {
  signedTx: string;
  orderResponse: object;
}

TypeScript Integration

TypeScript集成

Full Client Implementation

完整客户端实现

typescript
import { Connection, PublicKey, Transaction, Keypair } from '@solana/web3.js';

class SanctumClient {
  private apiKey: string;
  private baseUrl = 'https://sanctum-api.ironforge.network';
  private connection: Connection;

  constructor(apiKey: string, connection: Connection) {
    this.apiKey = apiKey;
    this.connection = connection;
  }

  // Get all LSTs
  async getLsts(): Promise<LstMetadata[]> {
    const response = await fetch(
      `${this.baseUrl}/lsts?apiKey=${this.apiKey}`
    );
    return response.json();
  }

  // Get specific LST
  async getLst(mintOrSymbol: string): Promise<LstMetadata> {
    const response = await fetch(
      `${this.baseUrl}/lsts/${mintOrSymbol}?apiKey=${this.apiKey}`
    );
    return response.json();
  }

  // Get swap quote
  async getSwapQuote(params: {
    inputMint: string;
    outputMint: string;
    amount: string;
    mode: 'ExactIn' | 'ExactOut';
    signer: string;
    slippageBps?: number;
  }): Promise<SwapOrderResponse> {
    const url = new URL(`${this.baseUrl}/swap/token/order`);
    url.searchParams.set('apiKey', this.apiKey);
    url.searchParams.set('inp', params.inputMint);
    url.searchParams.set('out', params.outputMint);
    url.searchParams.set('amt', params.amount);
    url.searchParams.set('mode', params.mode);
    url.searchParams.set('signer', params.signer);
    if (params.slippageBps) {
      url.searchParams.set('slippageBps', params.slippageBps.toString());
    }

    const response = await fetch(url.toString());
    return response.json();
  }

  // Execute swap
  async executeSwap(
    orderResponse: SwapOrderResponse,
    signer: Keypair
  ): Promise<string> {
    // Decode and sign transaction
    const txBuffer = Buffer.from(orderResponse.tx, 'base64');
    const transaction = Transaction.from(txBuffer);
    transaction.sign(signer);

    // Send to API
    const response = await fetch(`${this.baseUrl}/swap/token/execute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        signedTx: transaction.serialize().toString('base64'),
        orderResponse,
      }),
    });

    const result = await response.json();
    return result.txSignature;
  }

  // Swap LSTs (convenience method)
  async swapLst(params: {
    inputMint: string;
    outputMint: string;
    amount: string;
    signer: Keypair;
    slippageBps?: number;
  }): Promise<string> {
    const quote = await this.getSwapQuote({
      inputMint: params.inputMint,
      outputMint: params.outputMint,
      amount: params.amount,
      mode: 'ExactIn',
      signer: params.signer.publicKey.toBase58(),
      slippageBps: params.slippageBps || 50,
    });

    return this.executeSwap(quote, params.signer);
  }
}
typescript
import { Connection, PublicKey, Transaction, Keypair } from '@solana/web3.js';

class SanctumClient {
  private apiKey: string;
  private baseUrl = 'https://sanctum-api.ironforge.network';
  private connection: Connection;

  constructor(apiKey: string, connection: Connection) {
    this.apiKey = apiKey;
    this.connection = connection;
  }

  // 获取所有LST
  async getLsts(): Promise<LstMetadata[]> {
    const response = await fetch(
      `${this.baseUrl}/lsts?apiKey=${this.apiKey}`
    );
    return response.json();
  }

  // 获取特定LST
  async getLst(mintOrSymbol: string): Promise<LstMetadata> {
    const response = await fetch(
      `${this.baseUrl}/lsts/${mintOrSymbol}?apiKey=${this.apiKey}`
    );
    return response.json();
  }

  // 获取兑换报价
  async getSwapQuote(params: {
    inputMint: string;
    outputMint: string;
    amount: string;
    mode: 'ExactIn' | 'ExactOut';
    signer: string;
    slippageBps?: number;
  }): Promise<SwapOrderResponse> {
    const url = new URL(`${this.baseUrl}/swap/token/order`);
    url.searchParams.set('apiKey', this.apiKey);
    url.searchParams.set('inp', params.inputMint);
    url.searchParams.set('out', params.outputMint);
    url.searchParams.set('amt', params.amount);
    url.searchParams.set('mode', params.mode);
    url.searchParams.set('signer', params.signer);
    if (params.slippageBps) {
      url.searchParams.set('slippageBps', params.slippageBps.toString());
    }

    const response = await fetch(url.toString());
    return response.json();
  }

  // 执行兑换
  async executeSwap(
    orderResponse: SwapOrderResponse,
    signer: Keypair
  ): Promise<string> {
    // 解码并签名交易
    const txBuffer = Buffer.from(orderResponse.tx, 'base64');
    const transaction = Transaction.from(txBuffer);
    transaction.sign(signer);

    // 发送至API
    const response = await fetch(`${this.baseUrl}/swap/token/execute`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        signedTx: transaction.serialize().toString('base64'),
        orderResponse,
      }),
    });

    const result = await response.json();
    return result.txSignature;
  }

  // LST兑换(便捷方法)
  async swapLst(params: {
    inputMint: string;
    outputMint: string;
    amount: string;
    signer: Keypair;
    slippageBps?: number;
  }): Promise<string> {
    const quote = await this.getSwapQuote({
      inputMint: params.inputMint,
      outputMint: params.outputMint,
      amount: params.amount,
      mode: 'ExactIn',
      signer: params.signer.publicKey.toBase58(),
      slippageBps: params.slippageBps || 50,
    });

    return this.executeSwap(quote, params.signer);
  }
}

Usage Examples

使用示例

typescript
const connection = new Connection('https://api.mainnet-beta.solana.com');
const sanctum = new SanctumClient(API_KEY, connection);

// Get all LSTs
const lsts = await sanctum.getLsts();
console.log(`Found ${lsts.length} LSTs`);

// Get INF token info
const inf = await sanctum.getLst('INF');
console.log(`INF APY: ${inf.apy}%`);

// Swap 1 SOL to mSOL
const signature = await sanctum.swapLst({
  inputMint: LST_MINTS.SOL,
  outputMint: LST_MINTS.mSOL,
  amount: '1000000000', // 1 SOL (9 decimals)
  signer: wallet,
  slippageBps: 50,
});
console.log('Swap TX:', signature);

// Swap mSOL to INF
const infSwap = await sanctum.swapLst({
  inputMint: LST_MINTS.mSOL,
  outputMint: LST_MINTS.INF,
  amount: '500000000', // 0.5 mSOL
  signer: wallet,
});
typescript
const connection = new Connection('https://api.mainnet-beta.solana.com');
const sanctum = new SanctumClient(API_KEY, connection);

// 获取所有LST
const lsts = await sanctum.getLsts();
console.log(`找到${lsts.length}种LST`);

// 获取INF代币信息
const inf = await sanctum.getLst('INF');
console.log(`INF年化收益率: ${inf.apy}%`);

// 将1 SOL兑换为mSOL
const signature = await sanctum.swapLst({
  inputMint: LST_MINTS.SOL,
  outputMint: LST_MINTS.mSOL,
  amount: '1000000000', // 1 SOL(9位小数)
  signer: wallet,
  slippageBps: 50,
});
console.log('兑换交易签名:', signature);

// 将mSOL兑换为INF
const infSwap = await sanctum.swapLst({
  inputMint: LST_MINTS.mSOL,
  outputMint: LST_MINTS.INF,
  amount: '500000000', // 0.5 mSOL
  signer: wallet,
});

Infinity Pool

Infinity池

How It Works

工作原理

Infinity is a multi-LST liquidity pool enabling zero-slippage swaps:
  1. SOL Value Calculation: Each LST's value is calculated from on-chain stake pool state
  2. Fair Pricing: Swaps execute at intrinsic SOL value (no AMM curves)
  3. Fee Structure: 8 bps per swap, 10 bps for withdrawals
  4. Fee Distribution: 90% to LPs (INF holders), 10% to protocol
Infinity是支持零滑点兑换的多LST流动性池:
  1. SOL价值计算:每个LST的价值由链上质押池状态计算得出
  2. 公允定价:兑换按内在SOL价值执行(无AMM曲线)
  3. 手续费结构:每笔兑换收取8个基点,赎回收取10个基点
  4. 手续费分配:90%分配给流动性提供者(INF持有者),10%分配给协议

Add Liquidity (Get INF)

添加流动性(获取INF)

typescript
// Deposit SOL or any LST to get INF
async function addLiquidity(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair
): Promise<string> {
  // Swap LST/SOL for INF
  return sanctum.swapLst({
    inputMint: lstMint,
    outputMint: LST_MINTS.INF,
    amount,
    signer,
  });
}

// Example: Add 10 SOL to Infinity
const tx = await addLiquidity(
  sanctum,
  LST_MINTS.SOL,
  '10000000000',
  wallet
);
typescript
// 存入SOL或任意LST以获取INF
async function addLiquidity(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair
): Promise<string> {
  // 将LST/SOL兑换为INF
  return sanctum.swapLst({
    inputMint: lstMint,
    outputMint: LST_MINTS.INF,
    amount,
    signer,
  });
}

// 示例:向Infinity池存入10 SOL
const tx = await addLiquidity(
  sanctum,
  LST_MINTS.SOL,
  '10000000000',
  wallet
);

Remove Liquidity

移除流动性

typescript
// Withdraw from Infinity pool
async function removeLiquidity(
  sanctum: SanctumClient,
  outputMint: string,
  infAmount: string,
  signer: Keypair
): Promise<string> {
  // Swap INF for desired LST/SOL
  return sanctum.swapLst({
    inputMint: LST_MINTS.INF,
    outputMint: outputMint,
    amount: infAmount,
    signer,
  });
}

// Example: Withdraw to SOL
const tx = await removeLiquidity(
  sanctum,
  LST_MINTS.SOL,
  '5000000000', // 5 INF
  wallet
);
typescript
// 从Infinity池赎回
async function removeLiquidity(
  sanctum: SanctumClient,
  outputMint: string,
  infAmount: string,
  signer: Keypair
): Promise<string> {
  // 将INF兑换为目标LST/SOL
  return sanctum.swapLst({
    inputMint: LST_MINTS.INF,
    outputMint: outputMint,
    amount: infAmount,
    signer,
  });
}

// 示例:赎回为SOL
const tx = await removeLiquidity(
  sanctum,
  LST_MINTS.SOL,
  '5000000000', // 5 INF
  wallet
);

Router

路由模块

How Swaps Work

兑换工作原理

The Router enables LST-to-LST swaps via stake accounts:
  1. StakeWrappedSol: Stake SOL into pool, receive LST
  2. WithdrawWrappedSol: Withdraw undelegated SOL from reserve
  3. DepositStake: Deposit stake account, receive LST
  4. SwapViaStake: Route through shared validators
路由模块通过质押账户实现LST间兑换:
  1. StakeWrappedSol:将SOL质押至池,获取LST
  2. WithdrawWrappedSol:从储备池提取未委托的SOL
  3. DepositStake:存入质押账户,获取LST
  4. SwapViaStake:通过共享验证者路由

Fee Structure

手续费结构

OperationFee
StakeWrappedSol0 bps
WithdrawWrappedSol1 bps
DepositStake10 bps (waived for SOL output)
SwapViaStakeVaries by route
操作手续费
StakeWrappedSol0个基点
WithdrawWrappedSol1个基点
DepositStake10个基点(兑换为SOL时免除)
SwapViaStake依路由不同而变化

Jupiter Integration

Jupiter集成

Sanctum Router is integrated with Jupiter. Use Jupiter SDK for optimal routing:
typescript
import { Jupiter } from '@jup-ag/core';

const jupiter = await Jupiter.load({
  connection,
  cluster: 'mainnet-beta',
  user: wallet.publicKey,
});

// Jupiter automatically routes through Sanctum when optimal
const routes = await jupiter.computeRoutes({
  inputMint: new PublicKey(LST_MINTS.mSOL),
  outputMint: new PublicKey(LST_MINTS.jitoSOL),
  amount: 1_000_000_000n,
  slippageBps: 50,
});
Sanctum路由模块已与Jupiter集成。使用Jupiter SDK获取最优路由:
typescript
import { Jupiter } from '@jup-ag/core';

const jupiter = await Jupiter.load({
  connection,
  cluster: 'mainnet-beta',
  user: wallet.publicKey,
});

// 当路由最优时,Jupiter会自动通过Sanctum路由
const routes = await jupiter.computeRoutes({
  inputMint: new PublicKey(LST_MINTS.mSOL),
  outputMint: new PublicKey(LST_MINTS.jitoSOL),
  amount: 1_000_000_000n,
  slippageBps: 50,
});

Staking SOL

SOL质押

Direct Staking

直接质押

typescript
// Stake SOL to get LST
async function stakeSol(
  sanctum: SanctumClient,
  lstMint: string,
  solAmount: string,
  signer: Keypair
): Promise<string> {
  return sanctum.swapLst({
    inputMint: LST_MINTS.SOL,
    outputMint: lstMint,
    amount: solAmount,
    signer,
  });
}

// Stake 5 SOL for jupSOL
const tx = await stakeSol(
  sanctum,
  LST_MINTS.jupSOL,
  '5000000000',
  wallet
);
typescript
// 质押SOL以获取LST
async function stakeSol(
  sanctum: SanctumClient,
  lstMint: string,
  solAmount: string,
  signer: Keypair
): Promise<string> {
  return sanctum.swapLst({
    inputMint: LST_MINTS.SOL,
    outputMint: lstMint,
    amount: solAmount,
    signer,
  });
}

// 质押5 SOL以获取jupSOL
const tx = await stakeSol(
  sanctum,
  LST_MINTS.jupSOL,
  '5000000000',
  wallet
);

Unstaking (Instant)

即时赎回

typescript
// Instant unstake via Infinity/Reserve
async function instantUnstake(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair
): Promise<string> {
  return sanctum.swapLst({
    inputMint: lstMint,
    outputMint: LST_MINTS.SOL,
    amount,
    signer,
  });
}
typescript
// 通过Infinity/储备池即时赎回
async function instantUnstake(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair
): Promise<string> {
  return sanctum.swapLst({
    inputMint: lstMint,
    outputMint: LST_MINTS.SOL,
    amount,
    signer,
  });
}

Delayed Unstaking (Lower Fees)

延迟赎回(更低手续费)

typescript
// Withdraw to stake account (requires epoch wait)
async function delayedUnstake(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair,
  deactivate: boolean = true
): Promise<string> {
  const url = new URL(`${sanctum.baseUrl}/swap/withdrawStake/order`);
  url.searchParams.set('apiKey', sanctum.apiKey);
  url.searchParams.set('lstMint', lstMint);
  url.searchParams.set('amount', amount);
  url.searchParams.set('signer', signer.publicKey.toBase58());
  url.searchParams.set('deactivate', deactivate.toString());

  const response = await fetch(url.toString());
  const orderResponse = await response.json();

  return sanctum.executeSwap(orderResponse, signer);
}
typescript
// 赎回至质押账户(需等待一个周期)
async function delayedUnstake(
  sanctum: SanctumClient,
  lstMint: string,
  amount: string,
  signer: Keypair,
  deactivate: boolean = true
): Promise<string> {
  const url = new URL(`${sanctum.baseUrl}/swap/withdrawStake/order`);
  url.searchParams.set('apiKey', sanctum.apiKey);
  url.searchParams.set('lstMint', lstMint);
  url.searchParams.set('amount', amount);
  url.searchParams.set('signer', signer.publicKey.toBase58());
  url.searchParams.set('deactivate', deactivate.toString());

  const response = await fetch(url.toString());
  const orderResponse = await response.json();

  return sanctum.executeSwap(orderResponse, signer);
}

Data Queries

数据查询

Get APYs

获取APY

typescript
// 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;
}
typescript
// 获取所有LST的年化收益率
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;
}

// 获取特定LST的历史年化收益率
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

获取总锁仓价值

typescript
// 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;
}
typescript
// 获取特定LST的总锁仓价值
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

获取用户持仓

typescript
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;
}
typescript
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;
}

Program IDs

程序ID

Core Programs

核心程序

ProgramIDDescription
S Controller
5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx
Infinity pool management
Flat Fee Pricing
f1tUoNEKrDp1oeGn4zxr7bh41eN6VcfHjfrL3ZqQday
Fee calculation (deprecated)
Flat Slab
s1b6NRXj6ygNu1QMKXh2H9LUR2aPApAAm1UQ2DjdhNV
Current fee program
程序ID描述
S Controller
5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx
Infinity池管理
Flat Fee Pricing
f1tUoNEKrDp1oeGn4zxr7bh41eN6VcfHjfrL3ZqQday
手续费计算(已弃用)
Flat Slab
s1b6NRXj6ygNu1QMKXh2H9LUR2aPApAAm1UQ2DjdhNV
当前手续费程序

SOL Value Calculators

SOL价值计算器

CalculatorID
SPL
sp1V4h2gWorkGhVcazBc22Hfo2f5sd7jcjT4EDPrWFF
SanctumSpl
sspUE1vrh7xRoXxGsg7vR1zde2WdGtJRbyK9uRumBDy
SanctumSplMulti
ssmbu3KZxgonUtjEMCKspZzxvUQCxAFnyh1rcHUeEDo
Marinade
mare3SCyfZkAndpBRBeonETmkCCB3TJTTrz8ZN2dnhP
Lido
1idUSy4MGGKyKhvjSnGZ6Zc7Q4eKQcibym4BkEEw9KR
wSOL
wsoGmxQLSvwWpuaidCApxN5kEowLe2HLQLJhCQnj4bE
计算器ID
SPL
sp1V4h2gWorkGhVcazBc22Hfo2f5sd7jcjT4EDPrWFF
SanctumSpl
sspUE1vrh7xRoXxGsg7vR1zde2WdGtJRbyK9uRumBDy
SanctumSplMulti
ssmbu3KZxgonUtjEMCKspZzxvUQCxAFnyh1rcHUeEDo
Marinade
mare3SCyfZkAndpBRBeonETmkCCB3TJTTrz8ZN2dnhP
Lido
1idUSy4MGGKyKhvjSnGZ6Zc7Q4eKQcibym4BkEEw9KR
wSOL
wsoGmxQLSvwWpuaidCApxN5kEowLe2HLQLJhCQnj4bE

Stake Pool Programs

质押池程序

ProgramID
SanctumSpl Stake Pool
SP12tWFxD9oJsVWNavTTBZvMbA6gkAmxtVgxdqvyvhY
SanctumSplMulti Stake Pool
SPMBzsVUuoHA4Jm6KunbsotaahvVikZs1JyTW6iJvbn
程序ID
SanctumSpl Stake Pool
SP12tWFxD9oJsVWNavTTBZvMbA6gkAmxtVgxdqvyvhY
SanctumSplMulti Stake Pool
SPMBzsVUuoHA4Jm6KunbsotaahvVikZs1JyTW6iJvbn

Resources

资源

Skill Structure

Skill结构

sanctum/
├── SKILL.md                              # This file
├── resources/
│   ├── api-reference.md                  # Complete API documentation
│   ├── lst-reference.md                  # LST addresses and metadata
│   └── program-ids.md                    # All program addresses
├── examples/
│   ├── lst-swap/README.md                # LST swap examples
│   ├── staking/README.md                 # Staking/unstaking examples
│   ├── infinity-pool/README.md           # Infinity operations
│   └── liquidity/README.md               # Add/remove liquidity
└── docs/
    └── troubleshooting.md                # Common issues
sanctum/
├── SKILL.md                              # 本文档
├── resources/
│   ├── api-reference.md                  # 完整API文档
│   ├── lst-reference.md                  # LST地址和元数据
│   └── program-ids.md                    # 所有程序地址
├── examples/
│   ├── lst-swap/README.md                # LST兑换示例
│   ├── staking/README.md                 # 质押/赎回示例
│   ├── infinity-pool/README.md           # Infinity池操作示例
│   └── liquidity/README.md               # 添加/移除流动性示例
└── docs/
    └── troubleshooting.md                # 常见问题