Zum Hauptinhalt springen
Diese Seite wurde mit KI automatisch übersetzt. Maßgeblich ist stets die englische Version.Englische Version ansehen →
Versionsbanner.
  • SDK: @raydium-io/raydium-sdk-v2@0.2.42-alpha
  • Cluster: Solana mainnet-beta
  • Stable AMM Program ID: 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h (siehe reference/program-addresses)
  • Zuletzt verifiziert: 2026-04
Das liquidity-Modul des SDK verarbeitet Stable AMM Pools nativ. Stable Pools erscheinen als version: 5 (oder pooltype: "StablePool") auf ApiV3PoolInfoStandardItem; die gleichen addLiquidity / removeLiquidity / Swap-Helfer funktionieren für sie wie für AMM v4 (version: 4) Constant-Product-Pools — das SDK erkennt die Variante und gibt automatisch die korrekten Instruktionen aus. Die Off-Chain-Stable-Curve-Mathematik befindet sich in src/raydium/liquidity/stable.ts.

Setup

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",
  // Optional: Laden Sie das Stable-Curve-Modell-Layout, wenn Sie beabsichtigen,
  // Quoting-Helfer aus `liquidity/stable.ts` direkt aufzurufen. Pool-Level
  // Swap / Add / Remove tun dies träge für Sie, daher können die meisten
  // Aufrufer diesen Schritt überspringen.
});

// Einmalig: Prefetch die On-Chain-Modell-Datenlayout, die von den Off-Chain-
// Stable-Curve-Helfern verwendet wird. Nur erforderlich, wenn Sie getStablePrice /
// getDxByDyBaseIn / getDyByDxBaseIn direkt aufrufen. addLiquidity / removeLiquidity /
// swap benötigen dies nicht.
await raydium.liquidity.initLayout();

Einen Stable Pool identifizieren

Zwei äquivalente Signale auf ApiV3PoolInfoStandardItem:
const isStable =
  pool.version === 5 ||
  pool.pooltype.includes("StablePool"); // das SDK verwendet diese String-Prüfung intern

// Alternativ nach Program ID:
const STABLE_AMM_PROGRAM_ID = "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h";
const isStableByProgram = pool.programId === STABLE_AMM_PROGRAM_ID;
Sowohl AMM v4 (version: 4, Constant-Product) als auch Stable AMM (version: 5) fließen durch die gleiche LiquidityModule API im SDK. Intern verteilt das Modul auf:
  • InstructionType.AmmV4AddLiquidity / AmmV4RemoveLiquidity für v4 Pools
  • InstructionType.AmmV5AddLiquidity / AmmV5RemoveLiquidity für v5 (Stable) Pools
Die programId des Pools (zurückgegeben mit den Pool-Keys) teilt dem SDK mit, in welches Programm es CPI durchführen soll; Sie müssen es nicht hardcodieren.

Einen Pool nach Mint-Paar finden

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

// Zwei häufig verwendete Mints als Beispiel
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("Kein Stable Pool existiert für dieses Mint-Paar");
}

console.log("Stable Pool ID:", stablePool.id);
console.log("Stable Pool programId:", stablePool.programId);
console.log("TVL:", stablePool.tvl);
Wenn das Mint-Paar sowohl einen v4 (Constant-Product) Pool als auch einen v5 (Stable) Pool hat, enthält die Antwort beide — wählen Sie denjenigen, den Ihr Flow benötigt, oder übergeben Sie sie an das AMM Routing Programm und lassen Sie es die beste Route wählen.

Durch einen Stable Pool swappen

Der LiquidityModule.swap Flow hat die gleiche Form wie für v4 Pools — übergeben Sie einfach ein v5 Pool-Objekt:
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%

// Berechnen Sie die erwartete Ausgabe mit den Stable-Curve-Helfern des SDK intern.
const { amountOut, minAmountOut } = raydium.liquidity.computeAmountOut({
  poolInfo: stablePool,
  amountIn: inputAmount,
  mintIn:  stablePool.mintA.address,
  mintOut: stablePool.mintB.address,
  slippage,
});

console.log("Erwartete Ausgabe:", amountOut.toSignificant());
console.log("Minimale Ausgabe:", minAmountOut.toSignificant());

// Erstellen und signieren Sie die Swap-Transaktion.
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("Stable Swap Tx:", txId);
Das SDK liest die programId des Pools aus den Pool-Keys und verteilt in das Stable AMM Programm. Es ist kein spezielles programId-Argument erforderlich.

Liquidität hinzufügen und entfernen

addLiquidity und removeLiquidity funktionieren identisch über v4 und v5 Pools:
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%

// Berechnen Sie den entsprechenden B-Betrag, den die Kurve für diese Größe von A benötigt.
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("Add-Liquidity Tx:", txId);
Intern gibt das SDK InstructionType.AmmV5AddLiquidity aus, weil pooltype.includes("StablePool") wahr ist. Der entsprechende removeLiquidity Flow ist symmetrisch — geben Sie lpAmount und die Mindestbeträge ein, die Sie auf jeder Seite akzeptieren.

Off-Chain Quote Helfer (stable.ts)

Für serverseitige Quoting oder Backtesting stellt das SDK die zugrunde liegende Stable-Curve-Mathematik bereit:
import {
  getStablePrice,
  getDxByDyBaseIn,
  getDyByDxBaseIn,
} from "@raydium-io/raydium-sdk-v2";

// Sie müssen initLayout() einmal aufrufen, bevor Sie diese verwenden
// (lädt die On-Chain `ModelDataInfo` PDA in den StableLayout-Cache des SDK).
await raydium.liquidity.initLayout();

const modelData = raydium.liquidity.stableLayout;

// Spotpreis bei den aktuellen Reserven des Pools.
const price = getStablePrice(modelData, /* x */, /* y */, /* withFee */);
console.log("Spotpreis:", price);

// Quote: Gegeben dx rein, wie viel dy raus (keine Gebühr angewendet)?
const dyOut = getDyByDxBaseIn(modelData, /* x */, /* y */, /* dx */);

// Quote: Gegeben dy out Ziel, wie viel dx rein benötigt?
const dxIn  = getDxByDyBaseIn(modelData, /* x */, /* y */, /* dy */);
Dies sind reine Funktionen — kein RPC, kein Signieren. Die On-Chain ModelDataInfo wird einmal von initLayout() abgerufen und in raydium.liquidity.stableLayout zwischengespeichert. Übergeben Sie aktuelle Reserven (x, y) und die Helfer berechnen durch binäre Suche in der Nachschlagetabelle und lineare Interpolation zwischen den zwei umgebenden DataElement-Zeilen. Siehe products/stable/math für den zugrunde liegenden Algorithmus.

Routing durch AMM Routing (Multi-Hop / Best-Price)

Wenn Sie nicht selbst einen Ort wählen möchten, berücksichtigt das AMM Routing Programm jeden Raydium AMM (v4 / CPMM / CLMM / Stable) und leitet durch die beste Kombination:
const route = await raydium.tradeV2.fetchRoutes({
  inputMint:  mintA,
  outputMint: mintB,
  amount:     new BN(1_000_000),
  slippage,
});

// route.routes[0].poolType teilt Ihnen mit, welche Programme die beste Route verwendet;
// "Stable" erscheint hier, wenn ein Stable Pool Teil des optimalen Pfads ist.
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 });
Dies ist der empfohlene Pfad für Produktions-Swapper und Aggregatoren — Sie müssen nie manuell entscheiden, ob ein Stable Pool existiert oder ob er heute der bessere Ort ist.

Empfehlungen

  1. Für End-User-Swaps bevorzugen Sie den tradeV2 Routing-Flow. Er verarbeitet jeden Raydium Pool-Typ einschließlich Stable.
  2. Für Pool-spezifische Operationen (LP Add / Remove auf einem bekannten Stable Pool) verwenden Sie das LiquidityModule direkt — es erkennt v5 Pools automatisch.
  3. Für Off-Chain-Quoting / Analytics rufen Sie getStablePrice / getDyByDxBaseIn / getDxByDyBaseIn nach initLayout() auf. Kein RPC-Verkehr pro Quote nach dem Zwischenspeichern der Modelldaten.
  4. Codieren Sie nicht manuell rohe SwapBaseIn Instruktionen. Das 2026-06-22 Upgrade entfernte die toten OpenBook-Konten, daher benötigt das neue Swap-Layout 9 Konten (das alte 18-Konto-Layout wird immer noch für Rückwärtskompatibilität geparst). Deposit ist jetzt 12 Konten (alte 14 kompatibel), Withdraw 12 (alte 21/22 kompatibel), und WithdrawPnl 10 ohne Kompatibilitätspfad. Die vordefinierten Helfer des SDK wählen das korrekte Layout und die Reihenfolge für Sie aus; das Rollen Ihrer eigenen ist fehleranfällig. Siehe products/stable/instructions für die vollständigen Kontotabellen.

Wo es weitergeht

  • Math — wie die Nachschlagetabellen-Interpolation funktioniert.
  • Instructions — vollständige Instruktionsreferenz.
  • AMM Routing — Multi-Pool-Routing über AMM v4, CPMM, CLMM, Stable.
Quellen: