Chuyển đến nội dung chính
Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.Xem bản tiếng Anh →
Banner phiên bản.
  • SDK: @raydium-io/raydium-sdk-v2@0.2.42-alpha
  • Cluster: Solana mainnet-beta
  • ID chương trình Stable AMM: 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h (xem reference/program-addresses)
  • Xác minh lần cuối: 2026-04
Module liquidity của SDK hỗ trợ native các pool Stable AMM. Các pool Stable xuất hiện dưới dạng version: 5 (hoặc pooltype: "StablePool") trên ApiV3PoolInfoStandardItem; các trợ giúp addLiquidity / removeLiquidity / swap giống nhau cho cả pool v5 và pool constant-product AMM v4 (version: 4) — SDK phát hiện biến thể và phát hành các instruction chính xác tự động. Toán học stable-curve ngoài chuỗi nằm trong src/raydium/liquidity/stable.ts.

Thiết lập

npm install @raydium-io/raydium-sdk-v2 @solana/web3.js @solana/spl-token
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import { Connection, Keypair, clusterApiUrl } from "@solana/web3.js";
import BN from "bn.js";
import bs58 from "bs58";

const connection = new Connection(clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY!));

const raydium = await Raydium.load({
  connection,
  owner,
  cluster: "mainnet",
  // Tùy chọn: tải layout mô hình stable curve nếu bạn dự định gọi các trợ giúp
  // quoting từ `liquidity/stable.ts` trực tiếp. Swap / add / remove ở cấp pool
  // thực hiện điều này một cách lười biếng cho bạn, vì vậy hầu hết người gọi
  // có thể bỏ qua bước này.
});

// Một lần: tải trước layout dữ liệu mô hình trên chuỗi được sử dụng bởi các
// trợ giúp stable-curve ngoài chuỗi. Chỉ cần thiết nếu bạn gọi getStablePrice / getDxByDyBaseIn /
// getDyByDxBaseIn trực tiếp. addLiquidity / removeLiquidity / swap không cần điều này.
await raydium.liquidity.initLayout();

Xác định pool Stable

Hai tín hiệu tương đương trên ApiV3PoolInfoStandardItem:
const isStable =
  pool.version === 5 ||
  pool.pooltype.includes("StablePool"); // SDK sử dụng kiểm tra chuỗi này nội bộ

// Hoặc, theo ID chương trình:
const STABLE_AMM_PROGRAM_ID = "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h";
const isStableByProgram = pool.programId === STABLE_AMM_PROGRAM_ID;
Cả AMM v4 (version: 4, constant-product) và Stable AMM (version: 5) đều đi qua cùng một API LiquidityModule trên SDK. Nội bộ module điều phối đến:
  • InstructionType.AmmV4AddLiquidity / AmmV4RemoveLiquidity cho pool v4
  • InstructionType.AmmV5AddLiquidity / AmmV5RemoveLiquidity cho pool v5 (Stable)
programId của pool (được trả về cùng với các khóa pool) cho SDK biết chương trình nào để CPI vào; bạn không cần phải hardcode nó.

Tìm pool theo cặp mint

import { PublicKey } from "@solana/web3.js";

// Hai mint phổ biến để sử dụng làm ví dụ
const mintA = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); // USDT
const mintB = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC

const pools = await raydium.api.fetchPoolByMintPair({
  mint1: mintA.toBase58(),
  mint2: mintB.toBase58(),
});

const stablePool = pools.find(
  (p) => p.version === 5 || p.pooltype.includes("StablePool"),
);

if (!stablePool) {
  throw new Error("Không tồn tại pool Stable cho cặp mint này");
}

console.log("ID pool Stable:", stablePool.id);
console.log("ID chương trình pool Stable:", stablePool.programId);
console.log("TVL:", stablePool.tvl);
Nếu cặp mint có cả pool v4 (constant-product) và pool v5 (stable), phản hồi bao gồm cả hai — chọn cái mà luồng của bạn cần, hoặc chuyển chúng đến chương trình AMM Routing và để nó chọn tuyến đường tốt nhất.

Swap qua pool Stable

Luồng LiquidityModule.swap có cùng hình dạng như đối với pool v4 — chỉ cần chuyển nó một đối tượng pool v5:
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const inputAmount = new TokenAmount(toToken(stablePool.mintA), 1_000_000); // 1 USDT
const slippage = new Percent(50, 10_000); // 0.5%

// Tính toán đầu ra dự kiến bằng cách sử dụng các trợ giúp stable-curve của SDK nội bộ.
const { amountOut, minAmountOut } = raydium.liquidity.computeAmountOut({
  poolInfo: stablePool,
  amountIn: inputAmount,
  mintIn:  stablePool.mintA.address,
  mintOut: stablePool.mintB.address,
  slippage,
});

console.log("Đầu ra dự kiến:", amountOut.toSignificant());
console.log("Đầu ra tối thiểu:", minAmountOut.toSignificant());

// Xây dựng & ký giao dịch swap.
const { transaction, execute } = await raydium.liquidity.swap({
  poolInfo: stablePool,
  amountIn:    inputAmount.raw,
  amountOut:   minAmountOut.raw,
  fixedSide:   "in",
  txVersion:   TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Giao dịch swap Stable:", txId);
SDK đọc programId của pool từ các khóa pool và điều phối vào chương trình Stable AMM. Không cần đối số programId đặc biệt.

Thêm và loại bỏ thanh khoản

addLiquidityremoveLiquidity hoạt động giống hệt nhau trên các pool v4 và v5:
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const amountInA = new TokenAmount(toToken(stablePool.mintA), 100_000_000); // 100 USDT
const slippage  = new Percent(50, 10_000); // 0.5%

// Tính toán số lượng B phù hợp mà đường cong yêu cầu cho kích thước A này.
const { anotherAmount, minAnotherAmount } = raydium.liquidity.computePairAmount({
  poolInfo: stablePool,
  amount:   amountInA.toSignificant(),
  baseIn:   true,
  slippage,
});

const { execute } = await raydium.liquidity.addLiquidity({
  poolInfo: stablePool,
  amountInA,
  amountInB:      anotherAmount,
  otherAmountMin: minAnotherAmount,
  fixedSide:      "a",
  txVersion:      TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Giao dịch thêm thanh khoản:", txId);
Nội bộ SDK phát hành InstructionType.AmmV5AddLiquiditypooltype.includes("StablePool") là true. Luồng removeLiquidity tương ứng là đối xứng — nhập lpAmount và số lượng tối thiểu bạn sẽ chấp nhận ở mỗi bên.

Trợ giúp quote ngoài chuỗi (stable.ts)

Để quoting phía máy chủ hoặc backtesting, SDK công khai toán học stable-curve cơ bản:
import {
  getStablePrice,
  getDxByDyBaseIn,
  getDyByDxBaseIn,
} from "@raydium-io/raydium-sdk-v2";

// Bạn phải gọi initLayout() một lần trước khi sử dụng những cái này (tải
// layout dữ liệu mô hình `ModelDataInfo` trên chuỗi vào bộ nhớ cache StableLayout của SDK).
await raydium.liquidity.initLayout();

const modelData = raydium.liquidity.stableLayout;

// Giá spot tại dự trữ hiện tại của pool.
const price = getStablePrice(modelData, /* x */, /* y */, /* withFee */);
console.log("Giá spot:", price);

// Quote: cho dx vào, bao nhiêu dy ra (không áp dụng phí ở đây)?
const dyOut = getDyByDxBaseIn(modelData, /* x */, /* y */, /* dx */);

// Quote: cho mục tiêu dy ra, cần bao nhiêu dx vào?
const dxIn  = getDxByDyBaseIn(modelData, /* x */, /* y */, /* dy */);
Đây là các hàm thuần — không RPC, không ký. ModelDataInfo trên chuỗi được tải một lần bởi initLayout() và được lưu trong bộ nhớ cache trong raydium.liquidity.stableLayout. Chuyển dự trữ hiện tại (x, y) và các trợ giúp tính toán bằng cách tìm kiếm nhị phân bảng tra cứu và nội suy tuyến tính giữa hai hàng DataElement xung quanh. Xem products/stable/math để biết thuật toán cơ bản.

Định tuyến qua AMM Routing (multi-hop / giá tốt nhất)

Nếu bạn không muốn tự chọn một địa điểm, chương trình AMM Routing sẽ xem xét mọi AMM Raydium (v4 / CPMM / CLMM / Stable) và định tuyến qua bất kỳ kết hợp nào là tốt nhất:
const route = await raydium.tradeV2.fetchRoutes({
  inputMint:  mintA,
  outputMint: mintB,
  amount:     new BN(1_000_000),
  slippage,
});

// route.routes[0].poolType cho bạn biết chương trình nào mà tuyến đường tốt nhất sử dụng;
// "Stable" xuất hiện ở đây bất cứ khi nào pool Stable là một phần của đường dẫn tối ưu.
console.log(route.routes[0]);

const { execute } = await raydium.tradeV2.swap({
  inputMint:    mintA,
  outputMint:   mintB,
  inputAmount:  new BN(1_000_000),
  swapResult:   route.routes[0],
  slippage,
  txVersion:    TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
Đây là đường dẫn được khuyến nghị cho các swapper và aggregator sản xuất — bạn không bao giờ cần phải quyết định thủ công xem pool Stable có tồn tại hay không hoặc liệu nó có phải là địa điểm tốt hơn ngày hôm nay hay không.

Khuyến nghị

  1. Đối với swap của người dùng cuối, ưu tiên luồng định tuyến tradeV2. Nó xử lý mọi loại pool Raydium bao gồm Stable.
  2. Đối với các hoạt động cụ thể của pool (thêm / loại bỏ LP trên pool Stable đã biết), sử dụng LiquidityModule trực tiếp — nó tự động phát hiện pool v5.
  3. Đối với quoting / phân tích ngoài chuỗi, gọi getStablePrice / getDyByDxBaseIn / getDxByDyBaseIn sau initLayout(). Không có lưu lượng RPC cho mỗi quote sau khi dữ liệu mô hình được lưu trong bộ nhớ cache.
  4. Không mã hóa tay các instruction SwapBaseIn thô. Nâng cấp 2026-06-22 đã loại bỏ các tài khoản OpenBook chết, vì vậy layout swap mới lấy 9 tài khoản (layout 18 tài khoản cũ vẫn phân tích cú pháp để tương thích ngược). Deposit hiện là 12 tài khoản (14 cũ tương thích), Withdraw 12 (21/22 cũ tương thích), và WithdrawPnl 10 với không đường dẫn tương thích. Các trợ giúp được xây dựng sẵn của SDK chọn layout và thứ tự chính xác cho bạn; tự viết của bạn dễ bị lỗi. Xem products/stable/instructions để biết bảng tài khoản đầy đủ.

Tiếp theo đi đâu

  • Math — cách nội suy bảng tra cứu hoạt động.
  • Instructions — tham chiếu instruction đầy đủ.
  • AMM Routing — định tuyến multi-pool trên AMM v4, CPMM, CLMM, Stable.
Nguồn: