跳转到主要内容

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 自动翻译,所有内容以英文版本为准。查看英文版 →
AMM v4 的账户数量远多于 CPMM 或 CLMM,因为每项操作都涉及 OpenBook 状态。本页将账户分为”池拥有”和”OpenBook 拥有”两部分,方便集成者快速判断各类账户。

账户清单

AMM v4 池在创建时绑定到恰好一个 OpenBook 市场。完整的实时图景如下:
类别账户所有者用途
AmmInfoAMM v4 程序池状态:已累积手续费、状态、指向金库和 OpenBook 市场的引用
amm_authorityAMM v4 程序程序拥有的 PDA,对金库操作进行签名。在所有 AMM v4 池间共享
amm_open_ordersOpenBook池在该市场的 OpenBook OpenOrders 账户
amm_target_ordersAMM v4 程序池端目标限价订单网格,用于回发至 OpenBook
pool_coin_token_accountSPL Token池的币端金库(amm_authority 的 ATA)
pool_pc_token_accountSPL Token池的法币端金库
lp_mintSPL Token可互换的 LP 代币
pool_withdraw_queueAMM v4 程序延迟提取的历史队列;保持为零长度
pool_temp_lpAMM v4 程序Initialize 中使用的辅助 LP 账户
市场 (OpenBook)serum_marketOpenBook市场本身(基础/报价代币、金库签名者等)
市场serum_bids, serum_asksOpenBook买单和卖单队列
市场serum_event_queueOpenBook待处理事件(成交、撤单)
市场serum_coin_vault, serum_pc_vaultSPL TokenOpenBook 的市场级金库
市场serum_vault_signerOpenBook市场级 PDA,对 serum_*_vault 操作进行签名
注:为了向后兼容,AMM v4 的 IDL 和字段名中保留了”serum”前缀。它现在指代 OpenBook 市场。

AmmInfo

池的根状态账户。体积较大(约 752 字节),因为同时携带池和 OpenBook 引用。
// programs/amm/src/state.rs (简写;字段顺序/名称遵循 IDL)
pub struct AmmInfo {
    pub status: u64,           // 位掩码:swap/deposit/withdraw/crank 启用标志
    pub nonce:  u64,           // 用于推导 amm_authority 的 bump
    pub order_num: u64,
    pub depth: u64,
    pub coin_decimals: u64,
    pub pc_decimals:   u64,
    pub state:         u64,    // 内部状态机
    pub reset_flag:    u64,
    pub min_size:      u64,
    pub vol_max_cut_ratio: u64,
    pub amount_wave: u64,
    pub coin_lot_size: u64,    // 镜像 OpenBook 市场配置
    pub pc_lot_size:   u64,
    pub min_price_multiplier: u64,
    pub max_price_multiplier: u64,
    pub sys_decimal_value: u64,

    pub fees: Fees,            // 交易/协议/基金手续费率
    pub state_data: StateData,

    // 池拥有的账户:
    pub coin_vault: Pubkey,
    pub pc_vault:   Pubkey,
    pub coin_vault_mint: Pubkey,
    pub pc_vault_mint:   Pubkey,
    pub lp_mint:  Pubkey,
    pub open_orders: Pubkey,   // 池在 OpenBook 的 OpenOrders
    pub market: Pubkey,        // OpenBook 市场
    pub market_program: Pubkey, // OpenBook 程序 ID
    pub target_orders: Pubkey,
    pub withdraw_queue: Pubkey,
    pub lp_vault:       Pubkey, // = pool_temp_lp
    pub owner: Pubkey,          // 管理员(多签)
    pub lp_reserve: u64,
    pub padding: [u64; 3],
}

pub struct Fees {
    pub min_separate_numerator:   u64,     // 5
    pub min_separate_denominator: u64,     // 10_000
    pub trade_fee_numerator:      u64,     // 25  → OpenBook 集成使用
    pub trade_fee_denominator:    u64,     // 10_000
    pub pnl_numerator:            u64,     // 12  → 协议在 swap 手续费中的占比
    pub pnl_denominator:          u64,     // 100 → 因此 12/100 = 12% 手续费,= 交易量的 0.03%
    pub swap_fee_numerator:       u64,     // 25  → 0.25% 总 swap 手续费
    pub swap_fee_denominator:     u64,     // 10_000
}

pub struct StateData {
    pub need_take_pnl_coin: u64,
    pub need_take_pnl_pc:   u64,
    pub total_pnl_pc:   u64,
    pub total_pnl_coin: u64,
    pub pool_open_time: u64,
    pub punish_pc_amount: u64,
    pub punish_coin_amount: u64,
    pub orderbook_to_init_time: u64,
    pub swap_coin_in_amount: u128,
    pub swap_pc_out_amount:  u128,
    pub swap_acc_pc_fee:    u64,
    pub swap_pc_in_amount:  u128,
    pub swap_coin_out_amount: u128,
    pub swap_acc_coin_fee:  u64,
}
集成者需要关注的字段:
  • coin_vaultpc_vault — 池的 SPL Token 金库。按 Serum/OpenBook 惯例,cointoken_0(基础资产),pctoken_1(报价资产)。
  • coin_decimalspc_decimals — 与代币小数位数一致。
  • open_orderstarget_ordersmarket — 必须传递给每个 swap/deposit/withdraw 指令。
  • fees.swap_fee_numerator / swap_fee_denominator — 总交易手续费。默认 25 / 10_000 = 0.25%
  • status — 位掩码,控制操作的启用/禁用。由管理员通过 AdminSetStatus 设置。
  • state_data.need_take_pnl_* — 已累积手续费总额与已提取额之间的差额。TakePnl 将其清零。

OpenBook 接线

已停用。 AMM v4 池不再与 OpenBook 共享流动性 — 限价订单网格已被停用。本节描述的 OpenBook 账户仍然存在于每个池的 AmmInfo 中,并由 V1 swap 入口点验证(以及由 InitializeDepositWithdraw 验证),以保持向后兼容性。但实际上它们引用的链上状态为空。请使用 V2 swap 入口点 (SwapBaseInV2 / SwapBaseOutV2),它们完全跳过这些账户,代表当今的规范执行路径。
当你调用 AMM v4 池的任何 V1 读或写指令时,必须传递 OpenBook 账户。程序会重新推导并验证它们,传入不匹配的账户集合将被拒绝。(V2 swap 变体则不需要这些账户。)
const market = ...;  // OpenBook 市场 PublicKey

// OpenBook 在其市场账户上暴露的字段:
const marketDecoded = OpenBookMarket.decode(marketAccountData);
const {
  bids:           serumBids,
  asks:           serumAsks,
  eventQueue:     serumEventQueue,
  requestQueue:   serumRequestQueue,
  baseVault:      serumCoinVault,
  quoteVault:     serumPcVault,
  vaultSignerNonce,
} = marketDecoded;

const serumVaultSigner = PublicKey.createProgramAddressSync(
  [market.toBuffer(), u64ToBytes(vaultSignerNonce)],
  OPENBOOK_PROGRAM_ID,
);
AMM 的 amm_open_orders 是一个 OpenBook 拥有的账户,记录了池在该市场的限价订单状态:活跃订单、已结算余额、推荐人等。amm_target_orders 在 AMM 端:它保存了 AMM 的意图网格(每个订单槽的价格/数量),使程序能够低成本地与当前发布的订单进行比较,并执行差分的下单/撤单。

管理员 PDA

整个 AMM v4 程序恰好有一个 amm_authority PDA。其种子很简单(["amm authority"]),bump 存储在每个 AmmInfo 上。该管理员对所有 AMM v4 池的所有代币操作进行签名。
const AMM_V4_PROGRAM_ID = new PublicKey(
  "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8",
);
const [ammAuthority] = PublicKey.findProgramAddressSync(
  [Buffer.from("amm authority")],
  AMM_V4_PROGRAM_ID,
);
还有一个单独的池作用域管理员,按池推导,用于对 OpenBook 操作进行签名。(在该程序的设计中,amm_authority 实际上覆盖了两者;不同版本使用了不同的推导方式,因此在代码中应检查特定池的 AmmInfo.nonce

金库

池的 SPL Token 金库是标准代币账户,其 owneramm_authority。不是 ATA — 它们的地址是在 Initialize 时使用 ["amm_associated_seed", coin_mint_or_pc_mint, market, amm_id] 种子推导的特定 PDA。地址存储在 AmmInfo 上;推导是一次性的。 不支持 Token-2022。程序在所有金库操作中硬编码了 SPL Token 的程序 ID。尝试将 AMM v4 池绑定到 Token-2022 代币会在 Initialize 时失败。

LP 代币

标准 SPL Token 代币,其管理员是 amm_authority。总供应量追踪 LP 对池的所有权;燃烧 LP 会按比例从两个金库返回代币。因为 AMM v4 早于 CPMM,池状态中没有 lp_supply 镜像 — 直接读取链上代币的供应量。

状态位掩码

AmmInfo.status 控制操作。各位(位置可能因程序版本而异 — 请通过源代码确认):
标志效果
0SWAP_DISABLEDSwap* 被拒绝
1DEPOSIT_DISABLEDDeposit 被拒绝
2WITHDRAW_DISABLEDWithdraw 被拒绝
3CLMM_LIKE_MIGRATE运维使用的迁移门控标志
Raydium 多签通过 AdminCancelOrdersAdminSetParams 等设置这些位。

观察/预言机

AMM v4 没有专用的观察账户。 其他需要链上 TWAP 的协议通常间接消费 OpenBook 的订单簿交叉数据或读取链下数据。如果你需要具有程序支持的 Raydium TWAP,请使用 CPMM 或 CLMM。

从头推导池的账户

因为 AMM v4 不是为确定性的每对 PDA 而设计的(它早于该 Solana 惯例),规范的 amm_id 是一个带种子的密钥对,推导方式为:
ammId = createWithSeed(
  owner: ammAuthority,
  seed:  marketPubkey.toBase58().slice(0, 32),
  programId: AMM_V4_PROGRAM_ID,
)
同样的带种子密钥模式适用于 amm_open_ordersamm_target_ordersamm_withdraw_queuepool_temp_lppool_coin_token_accountpool_pc_token_accountlp_mint。SDK 和 API 为你预计算这些;参见 raydium-sdk-v2Liquidity.getAssociatedPoolKeys 实际上,集成者从 GET https://api-v3.raydium.io/pools/info/ids?ids=<POOL_ID> 或从 SDK 读取池的完整账户集合。手动推导很少需要。

生命周期快速参考

事件创建的账户销毁的账户
Initialize2amm_infoamm_open_ordersamm_target_orders、金库、lp_mintpool_withdraw_queuepool_temp_lp
Deposit—(可能创建用户 LP ATA)
Withdraw
SwapBaseIn / SwapBaseOut—(可能创建用户 ATA)
TakePnl
MonitorStep(crank)
池及其账户无限期保留。即使流动性完全提出,AmmInfo 仍然存在。

在哪里阅读什么

来源: