跳转到主要内容

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 自动翻译,所有内容以英文版本为准。查看英文版 →
版本信息。
  • SDK: @raydium-io/raydium-sdk-v2@0.2.42-alpha
  • 集群: Solana mainnet-beta
  • 程序 ID: 见 reference/program-addresses
  • 最后验证: 2026-04
package.json 中固定 SDK 版本。黏合曲线接口在次版本间有所演变。

设置

本节演示对应 raydium-sdk-V2-demo/src/launchpad 中的文件。引导步骤遵循演示仓库的 config.ts.template
import { Connection, Keypair, clusterApiUrl, PublicKey } from "@solana/web3.js";
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";
import fs from "node:fs";

const connection = new Connection(process.env.RPC_URL ?? clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(
  new Uint8Array(JSON.parse(fs.readFileSync(process.env.KEYPAIR!, "utf8"))),
);
const raydium = await Raydium.load({
  owner,
  connection,
  cluster: "mainnet",
  disableFeatureCheck: true,
  blockhashCommitment: "finalized",
});
export const txVersion = TxVersion.V0;

创建启动

源代码: src/launchpad/createMint.ts(以及 createBonkMintApi.ts 用于 API 驱动的 Bonk 变体)
import { NATIVE_MINT } from "@solana/spl-token";

const { execute, extInfo } = await raydium.launchpad.createLaunchpad({
  programId: /* LaunchLab program ID from reference/program-addresses */,
  // Token metadata for the new base mint:
  name:   "Example Token",
  symbol: "EXMPL",
  uri:    "https://example.com/metadata.json",
  decimals: 6,

  // Curve params:
  curveType: 0,                                      // 0 = quadratic
  supply:    new BN(1_000_000_000).mul(new BN(10).pow(new BN(6))), // 1B base (6 dec)
  graduationFractionBps: 8000,                       // 80% → graduation
  initialK:  new BN("40"),                           // curve shape parameter

  // Quote side:
  quoteMint: NATIVE_MINT,                            // WSOL
  openTime:  new BN(Math.floor(Date.now() / 1000) + 60),  // opens in 1min

  // Fee policy:
  fees: {
    buyNumerator:   new BN(100),                     // 1.00%
    buyDenominator: new BN(10_000),
    sellNumerator:  new BN(100),
    sellDenominator: new BN(10_000),
    lpShare:         new BN(60),
    creatorShare:    new BN(20),
    protocolShare:   new BN(20),
    totalShare:      new BN(100),
  },

  postGraduationLpPolicy: "burn",                    // "burn" | "lock" | "toCreator"

  txVersion: TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Launch:", extInfo.launchState.toBase58());
console.log("Base mint:", extInfo.baseMint.toBase58());
console.log("Create tx:", txId);
注意:
  • initialK 是二次曲线的缩放因子。调整它可针对毕业时的特定开盘 CPMM 价格。参见 products/launchlab/bonding-curve 了解推导过程。
  • SDK 在单个事务中处理创建基础 token、元数据 PDA 和两个保管库。如果元数据 URI 很长,可能超过 1232 字节;此时 SDK 会分成两个事务。
  • Initialize 之后,启动在 openTime 前不可交易。将 openTime 设置为提前一两分钟,以减少抢跑者的机会。

获取启动状态

const launchId = new PublicKey("<LAUNCH_STATE>");

const launch = await raydium.launchpad.getLaunchById({ launchId });
console.log("Status:", ["Active","Graduated","Cancelled"][launch.status]);
console.log("Base sold:", launch.baseSold.toString(),
            "/", launch.baseSupplyMax.toString());
console.log("Quote collected:", launch.quoteReserveReal.toString(),
            "target:", launch.quoteReserveTarget.toString());
if (launch.status === 1) {
  console.log("Post-graduation CPMM pool:", launch.cpmmPoolState.toBase58());
}
getLaunchById 返回解码后的 LaunchState 以及计算得出的「毕业进度」分数(以 Decimal 形式)。

买入 — 精确报价输入

源代码: src/launchpad/buy.ts
const quoteIn        = new BN(1).mul(new BN(10).pow(new BN(9)));  // 1 SOL
const minimumBaseOut = new BN(0);  // accept any; tighten for production

// Preview the quote off-chain so your UI can show expected base_out:
const preview = raydium.launchpad.computeBuyBase({
  launchState: launch,
  quoteIn,
});
console.log("Expected base_out:", preview.baseOut.toString(),
            "price impact:", preview.priceImpact.toString());

const { execute } = await raydium.launchpad.buyExactIn({
  launchInfo: launch,
  quoteIn,
  minimumBaseOut,
  txVersion: TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Buy tx:", txId);
computeBuyBase 镜像链上 Newton 求解器(二次曲线)或闭式 CPMM 逆向(curve_type 1)。用它来填充「你将收到」UI 字段。

买入 — 精确基础输出

const baseOut         = new BN(1_000_000).mul(new BN(10).pow(new BN(6)));  // 1M base
const maximumQuoteIn  = new BN(2).mul(new BN(10).pow(new BN(9)));          // cap at 2 SOL

const { execute } = await raydium.launchpad.buyExactOut({
  launchInfo: launch,
  baseOut,
  maximumQuoteIn,
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
适用于「恰好买 X 个 token」的 UI。如果曲线移动幅度太大,导致报价需求现已超过 maximumQuoteIn,则以 ExceededSlippage 拒绝。

卖出

源代码: src/launchpad/sell.ts
const baseIn           = new BN(500_000).mul(new BN(10).pow(new BN(6)));  // 0.5M base
const minimumQuoteOut  = new BN(0);

const { execute } = await raydium.launchpad.sellExactIn({
  launchInfo: launch,
  baseIn,
  minimumQuoteOut,
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
曲线的卖出路径与买入路径对称:将 base_sold 减少 baseIn 后返回的 quote_out 等于曲线在 base_sold − baseInbase_sold 之间的积分面积,减去卖出费用。

在阈值交叉买入时自动毕业

当 SDK 检测到买入后的状态将跨越阈值时,它会在 buy* 事务中链接 Graduate 指令:
const { execute, willGraduate } = await raydium.launchpad.buyExactIn({
  launchInfo: launch,
  quoteIn: new BN(100).mul(new BN(10).pow(new BN(9))),    // large buy
  minimumBaseOut: new BN(0),
  txVersion: TxVersion.V0,
  autoGraduate: true,                                      // default
});

if (willGraduate) {
  console.log("This buy will trigger graduation.");
}

const { txId } = await execute({ sendAndConfirm: true });
因为 Graduate 是无权限的,任何人(包括 MEV 机器人)都可以争相在阈值跨越后首次执行 Graduate — 通常在几秒内,而不是几分钟。首次成功的人只需支付 CPMM 池账户的租赁费;他们没有其他好处。

手动 Graduate

如果 autoGraduate 关闭或阈值交叉事务失败,你可以单独执行毕业:
const { execute } = await raydium.launchpad.graduate({
  launchInfo: launch,
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
如果在提交时 quote_reserve_real < quote_reserve_target,则以 NotAtThreshold 拒绝。可重试安全 — 成功后的第二次 Graduate 尝试将以 NotActive 拒绝。

收集创建者费用

源代码: src/launchpad/claimCreatorFee.ts(单个 token)和 collectAllCreatorFees.ts(批处理)
const { execute } = await raydium.launchpad.collectCreatorFees({
  launchInfo: launch,
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
将累积的创建者费用计数器报价金额转移到创建者在报价 token 上的 ATA。可在毕业前或后调用;定期使用而不是等待余额积累到很大。

通过生命周期追踪启动

整合在一起,监控脚本可能如下所示:
async function watch(launchId: PublicKey) {
  while (true) {
    const launch = await raydium.launchpad.getLaunchById({ launchId });
    const progress =
      Number(launch.quoteReserveReal) /
      Number(launch.quoteReserveTarget);

    console.log(
      `status=${["Active","Graduated","Cancelled"][launch.status]}`,
      `progress=${(progress * 100).toFixed(2)}%`,
      `num_buys=${launch.stateData.numBuys}`,
    );

    if (launch.status === 1) {
      console.log("Graduated to CPMM pool:", launch.cpmmPoolState.toBase58());
      break;
    }
    await new Promise(r => setTimeout(r, 10_000));
  }
}

Rust CPI

从你自己的 Anchor 程序调用 LaunchLab 很少见(大多数启动集成仅在 TS 一侧)。如果要这样做,程序提供 Anchor crate raydium_launchlab,其中包含 cpi::accounts::Buycpi::accounts::Sell 等 — 模式镜像 CPMM/CLMM CPI 示例。当该网站被填充时,参见 sdk-api/rust-cpi 获取通用模板。

陷阱

  • 费用分割算术偏差一。 如果 total_share 不完全等于 lp_share + creator_share + protocol_shareInitialize 将以 InvalidFeeShares 拒绝。将 totalShare 设置为相加总和。
  • 使用非允许的报价 token。 launch_config.allowed_quote_mints 是固定列表;传入任何其他 token 将拒绝。首先用 raydium.launchpad.getConfig() 检查。
  • 元数据大小。uri 字符串会让 Metaplex CPI 超出预算。保持 uri 在 ~200 字符以下 — 大多数 CDN 托管的 JSON 元数据轻松适配。
  • 毕业竞争。 自动化机器人监控 quote_reserve_real 并在阈值跨越后一两个 slot 内抢跑 Graduate。这是无害的 — 只需他们支付租赁费 — 但意味着你的 UI 应将 status 转换视为快速事件。

接下来在哪里

源代码: