Yang dilakukan halaman ini. Memuat pool CPMM dari RPC, mengutip swap dengan slippage 0,5%, membangun transaksi, menandatangani dengan keypair Anda, dan mengirimkannya. End-to-end dalam ~30 baris.
Setup
Pastikan Anda telah membaca prasyarat Quick start dan memiliki RPC_URL, KEYPAIR, serta dependensi yang sudah dipasang.
Skrip
Simpan sebagai swap.mjs:
// swap.mjs
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import { Raydium, TxVersion, CurveCalculator } from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";
import fs from "node:fs";
// ── Config from env ──────────────────────────────────────────────
const RPC_URL = process.env.RPC_URL ?? "https://api.mainnet-beta.solana.com";
const KEYPAIR = process.env.KEYPAIR ?? `${process.env.HOME}/.config/solana/id.json`;
const POOL_ID = process.env.POOL_ID; // required, base58
const INPUT_MINT = process.env.INPUT_MINT; // required, base58
const AMOUNT_RAW = process.env.AMOUNT_RAW; // required, integer in raw units (e.g. 1_000_000_000 for 1 SOL)
if (!POOL_ID || !INPUT_MINT || !AMOUNT_RAW) {
console.error("Set POOL_ID, INPUT_MINT, AMOUNT_RAW env vars.");
process.exit(1);
}
// ── Setup ────────────────────────────────────────────────────────
const connection = new Connection(RPC_URL, "confirmed");
const owner = Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync(KEYPAIR, "utf8"))),
);
const raydium = await Raydium.load({
owner,
connection,
cluster: "mainnet",
disableFeatureCheck: true,
blockhashCommitment: "finalized",
});
// ── Load pool ────────────────────────────────────────────────────
const { poolInfo, poolKeys, rpcData } =
await raydium.cpmm.getPoolInfoFromRpc(new PublicKey(POOL_ID));
const baseIn = poolInfo.mintA.address === INPUT_MINT;
// ── Quote ────────────────────────────────────────────────────────
const inputAmount = new BN(AMOUNT_RAW);
const swapResult = CurveCalculator.swap(
inputAmount,
baseIn ? rpcData.baseReserve : rpcData.quoteReserve,
baseIn ? rpcData.quoteReserve : rpcData.baseReserve,
rpcData.configInfo.tradeFeeRate,
);
console.log(`Quote: ${inputAmount.toString()} -> ${swapResult.destinationAmountSwapped.toString()}`);
console.log(`Fee: ${swapResult.tradeFee.toString()}`);
// ── Build and execute ────────────────────────────────────────────
const { execute } = await raydium.cpmm.swap({
poolInfo,
poolKeys,
inputAmount,
swapResult,
slippage: 0.005, // 0.5%
baseIn,
txVersion: TxVersion.V0,
computeBudgetConfig: {
units: 250_000,
microLamports: 50_000,
},
});
const { txId } = await execute({ sendAndConfirm: true });
console.log(`Swap landed: https://solscan.io/tx/${txId}`);
Jalankan
Pilih pool CPMM apa pun yang Anda miliki likuiditas. Contoh dengan pool CPMM SOL/USDC kanonik:
export POOL_ID="<tempel ID pool CPMM — cari satu di tab Pools UI Raydium>"
export INPUT_MINT="So11111111111111111111111111111111111111112"
export AMOUNT_RAW="10000000" # 0.01 SOL
node swap.mjs
Output yang diharapkan:
Quote: 10000000 -> 1640000
Fee: 25000
Swap landed: https://solscan.io/tx/4Z9...
Apa yang baru saja terjadi
Raydium.load menginisialisasi SDK — mengambil konfigurasi global dan menyiapkan konteks dompet Anda.
getPoolInfoFromRpc menarik status pool live langsung dari RPC (bukan dari cache API). Untuk swap bernilai tinggi, Anda selalu menginginkan status terbaru.
CurveCalculator.swap menghitung output constant-product setelah dipotong biaya pool. Ini adalah matematika yang sama yang dijalankan program on-chain, sehingga Anda dapat membandingkan kutipan off-chain dan on-chain.
raydium.cpmm.swap membangun transaksi dengan format V0 (address lookup tables diaktifkan) dan menambahkan konfigurasi compute-budget eksplisit. Tip compute-budget membantu transaksi masuk di jendela sibuk.
execute({ sendAndConfirm: true }) menandatangani, mengirim, dan menunggu konfirmasi.
Kesalahan umum
Pool not found — POOL_ID salah, atau Anda menunjuk cluster yang salah (ID pool mainnet melawan RPC devnet, dll.).
Insufficient funds for transaction — Dompet Anda tidak memiliki cukup SOL untuk input swap + biaya + sewa ATA.
Slippage tolerance exceeded — Harga pool bergerak antara kutipan dan eksekusi. Jalankan ulang; atau naikkan parameter slippage; atau gunakan computeAmountOut SDK yang selalu mengambil ulang reserves.
Token account not initialized — ATA token output tidak ada dan instruksi implicit-create masuk tetapi gagal karena beberapa alasan; periksa saldo SOL dompet Anda dan coba lagi.
Selanjutnya