Skip to main content
本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →

IDL 是什么

Solana 上的 Anchor 程序发布 IDL(接口定义语言)文件,描述其指令、账户布局、错误枚举和结构体模式。IDL 是客户端代码生成的真实来源——TS SDK、Rust CPI crate 和第三方客户端都是从它生成的(或针对它手写的)。 Raydium 为 CPMM、CLMM 和 LaunchLab 发布 IDL。AMM v4、Stable AMM 和 Farm(v3 / v5 / v6)早于 Anchor 或以其他方式不是 Anchor 分发的——它们的账户结构在 SDK 中手动维护。

在哪里找到它们

IDL 存放在专门的仓库中:
具体文件: IDL 文件在仓库的 git 历史中有版本控制;如果需要字节级别的可重现性,请固定到特定的提交。 某些 IDL 也可以直接从主网拉取:
现在有两种 on-chain IDL 机制,Raydium 的程序分布在它们之间——这很重要,因为给定的 Anchor CLI 版本可能只知道其中一种:
CPMM 没有旧版 anchor:idl 账户。 其 IDL 已迁移到 Program Metadata 程序,因此 anchor idl fetch CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C 在任何仅检查旧版 PDA 的 Anchor CLI 上都会失败。使用 SDK 附带的 IDL,或读取上面的元数据账户,直到你的 CLI 支持元数据程序。
所有三个旧版 IDL 账户都可由 IDL 权限 2XVnob28A5Qnpcy95UVeHWNT6G8Poy3tpA3AFyAMoZDt 写入,这与程序的 BPF 升级权限分开——因此可以在不重新部署的情况下刷新 IDL,也可能滞后于重新部署。将 on-chain IDL 视为便利,而不是已部署字节码形状的证明。

重新生成 TypeScript 客户端

Anchor 的代码生成从 IDL 生成类型化客户端:
大多数集成者这样做——他们使用更高级的 raydium.cpmm.swap(...) 助手,它包装了 Anchor 方法加上所有的簿记(ATA 创建、转账费调整、计算预算、Token-2022 程序路由)。仅在需要 SDK 下面的层时重新生成。

重新生成 Rust 客户端(CPI crate)

Raydium 为具有 IDL 的程序发布 Anchor crate:
在代码中,按其名称 raydium_cp_swapraydium_clmm 引用它们。没有任何拼写的 raydium_amm_v3 crate。注意分支不同:raydium-cp-swapmaster 仍然固定 anchor-lang 0.32.1,因此 Anchor-1.0 集成需要 chore/upgrade-anchor;CLMM 无论哪种方式都在 0.32.1 上,这就是为什么两者不能共享一个 crate。 cpi 特性暴露 cpi::accounts::<Ix> 账户结构体和 cpi::<ix>() 调用器——现成的 CPI 包装器。参见 sdk-api/rust-cpi 了解使用模式。 如果你更喜欢生成新的绑定:

重新生成 Python 客户端

没有官方的 Raydium Python SDK。第三方生成器包括:
  • anchorpy ——Anchor 的 TypeScript 客户端的 Python 端口。从 IDL 生成类型化方法构建器。
  • solders ——低级 Solana 原语(交易、密钥对、公钥)在 Rust 绑定中;在 anchorpy 下面使用。
参见 sdk-api/python-integration 了解更完整的演练。

IDL 变更政策

Raydium 遵循以下 IDL 稳定性规则:
  1. 指令判别器永不改变。 添加新指令在末尾扩展枚举;现有判别器保持稳定。
  2. 账户大小稳定;新字段来自保留填充。 每个 Raydium 状态结构体在创建时都带有尾部填充区域,新字段从该填充中切割出来而不是追加——因此账户的字节长度和所有预先存在的字段的偏移量保持固定。推论是你之前读作填充的字节可能变成有意义的,字段可以退回到填充中(如 2026-08-31 版本中的 PlatformConfig.curve_params)。升级后重新读取结构体定义;不要假设填充保持为零。
  3. 错误枚举代码仅追加。 现有错误代码始终意味着相同的事情。
  4. 破坏性变更在新程序中发布。 当需要重新设计时,团队部署新的程序 ID(例如 CPMM 作为新程序而不是升级 AMM v4)。旧池继续在旧程序上运行;新池转到新程序。
此政策使重新生成的客户端大多向后兼容:针对较旧 IDL 生成的客户端继续解码它知道的字段,在它知道的偏移量处。它不会看到的是从它仍然视为填充的内容中切割出来的字段——以及在罕见的退休情况下,它解码的字段可能不再被写入。它不会看到”额外的尾部字节”:账户长度不会改变。

IDL 变更时该怎么办

  1. 更新 SDK。 npm update @raydium-io/raydium-sdk-v2
  2. 重新生成你的客户端代码,如果你直接使用 Anchor 代码生成。
  3. 比较账户布局。 新布局的尾部字段是你的代码还没看到的唯一东西;确认你是否需要它们。
  4. 不要假设旧指令判别器无效。 根据规则 1,它们仍然有效。
  5. 在推送到主网之前,针对 devnet 重新运行集成测试

IDL 故障排除

”Invalid discriminator”(无效判别器)错误

通常意味着针对 IDL 版本 N 构建的客户端试图调用仅在程序的预部署版本中存在的指令。从实时程序重新拉取 IDL:
对于 CPMM,这不会工作——参见上面的 IDL 位置表;改为拉取 SDK 的捆绑 IDL。

账户解码失败

如果 program.account.<Name>.fetch(pubkey) 抛出”Invalid account discriminator”,账户是由先前的程序版本创建的,Anchor 拒绝其 8 字节判别器。修复是使用 SDK 中的原始布局解析器(PoolInfoLayout.decode(accountData)),它不强制 Anchor 判别器。

生成的客户端中缺少指令

Anchor 的 TS 代码生成仅为 IDL 条目有 name 的指令生成方法,该名称解析为有效标识符。Raydium 的指令都满足这一点,但如果你看到不匹配,检查 IDL 文件是否来自当前 SDK 版本。

指针

来源: