跳轉到主要內容

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
這個指令碼的功能。 從 RPC 載入 CPMM 池,以 0.5% 滑點報價交換,建立交易,使用你的金鑰對簽署,並提交。整個過程只需約 30 行程式碼。

設定

確保你已閱讀 快速開始必要條件,並已安裝 RPC_URLKEYPAIR 和相依套件。

指令碼

另存為 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}`);

執行

選擇任何你有流動性的 CPMM 池。以規範的 SOL/USDC CPMM 池為例:
export POOL_ID="<貼上 CPMM 池 ID — 在 Raydium UI 的「池」分頁找一個>"
export INPUT_MINT="So11111111111111111111111111111111111111112"
export AMOUNT_RAW="10000000"   # 0.01 SOL

node swap.mjs
預期輸出:
Quote: 10000000 -> 1640000
Fee:   25000
Swap landed: https://solscan.io/tx/4Z9...

剛才發生了什麼

  1. Raydium.load 初始化 SDK — 擷取全域設定,設定你的錢包環境。
  2. getPoolInfoFromRpc 直接從 RPC 提取即時池狀態(而不是從 API 快取)。高價值交換時,你總是希望得到最新狀態。
  3. CurveCalculator.swap 計算常數乘積輸出,扣除池的手續費。這是程式在鏈上執行的相同數學運算,因此你可以比較離線和鏈上報價。
  4. raydium.cpmm.swap 使用 V0 格式(啟用位址查詢表)建立交易,並新增明確的計算預算設定。計算預算提示有助於在繁忙時段讓交易著陸。
  5. execute({ sendAndConfirm: true }) 簽署、發送並等待確認。

常見錯誤

  • Pool not found — 錯誤的 POOL_ID,或你指向了錯誤的叢集(mainnet 池 ID 對著 devnet RPC 等)。
  • Insufficient funds for transaction — 你的錢包沒有足夠的 SOL 來支付交換輸入 + 手續費 + ATA 租金。
  • Slippage tolerance exceeded — 池的價格在報價和執行之間發生變動。重新執行;或提高 slippage 參數;或使用 SDK 的 computeAmountOut,它總是重新擷取準備金。
  • Token account not initialized — 輸出代幣的 ATA 不存在,隱式建立指令著陸但因某種原因失敗;檢查你的錢包 SOL 餘額並重試。

下一步