Skip to main content
Solana 程序发布了一个经过验证的 IDL 包:每个程序一个 Anchor IDL、一个共享错误目录、一份来源记录,以及生成的 TypeScript 类型。这些 IDL 是标准的 Anchor 0.31.1 输出,并修正了客户端元数据;程序本身没有任何改动。本页列出这些文件,以及由于 IDL 无法表达、你必须手动遵循的规则。 每个程序的职责见 Solana 程序。

下载

与每个 IDL 对应的 TypeScript 类型见下方的 TypeScript 类型。请将 JSON 文件与类型一起使用;自行运行 anchor build 得到的是未经本页所述修正的原始 IDL。

需要自行派生的账户

程序中有十处 PDA 表达式会对指令参数做哈希或调用方法,而 Anchor 的自动账户解析器无法执行它们。已发布的 IDL 去掉了这些 pda 提示,因此 Anchor 不会自动填入这些账户。请在客户端派生它们并显式传入: 请在第一列所列程序下派生各个 PDA。fill_id 和 fill_record 是同一个地址的两个名字。

规范订单 ID

使用哪个值取决于订单源自哪里:
  • 输入结算器指令(open、finalise、refund、refund_on_non_fill)以及紧凑同链填充(fill_samechain、native_fill_samechain)使用 keccak256(Borsh(StandardOrder))——对输入结算器是已签名的订单,对紧凑路径是完全展开后的订单。永远不要用 JSON、紧凑订单字节或 SHA-256 摘要的哈希来代替。
  • 普通输出填充(fill、native_fill、attest_not_filled)将 order_id 作为参数接收,且不会验证它。请逐字节传入源链的订单标识符,与该链输入结算器计算出的完全一致。只有在 Solana 托管上开启的订单,该值才是上面的 Borsh 哈希;对于源自 EVM 或其他链的订单,请使用该链自己的订单 ID。以其他任何值记录的填充都无法为该订单结算。

规范输出哈希

输出哈希是对以下紧凑打包编码计算的 keccak-256——而不是 MandateOutput 的 Borsh 编码:
chain_id 和 amount 取其 32 字节大端序值,每个变长字段都必须能放进一个 u16。 对于紧凑同链填充,请先像程序那样展开输出:oracle 和 settler 为输出结算器的状态 PDA,chain_id 来自该状态,token 为铸币(原生 SOL 为 32 字节的零),amount 为 output_amount,recipient 为接收方账户,callback_data 为空。context 在 None 时为空,否则为 0xe0 || exclusive_for[32] || start_time[u32 big-endian]——ExclusiveForSelf 使用填充者的公钥作为 exclusive_for。

示例:派生托管账户

allOtherOpenAccounts 必须包含 open 的其他所有具名账户,因为 accountsStrict 会关闭整条指令的自动解析。请使用 TypeScript 类型中的驼峰式账户名和参数名。构建指令并不会检查余额、所有权、哈希或链上状态。请启用 TypeScript 的 strict(至少 strictNullChecks),以便 Anchor 的账户类型能区分必需账户和可选账户。

紧凑同链填充

fill_samechain 和 native_fill_samechain 必须在同一笔交易中、紧跟在一个匹配的 finalise_with_prefill 之后执行。它们不会创建 LocalAttestation。永远不要单独提交它们,也不要用它们代替普通填充。
所需的指令顺序,全部位于一笔交易中:
finalise_with_prefill 会向后查找匹配的紧凑填充,并在释放托管资金之前,将传入的订单 ID 与展开后的订单绑定。紧凑填充的处理逻辑自身不会检查前面是否有结算指令,因此单独的紧凑填充会支付输出,却让求解器没有任何可据以领取的东西。完整工作流见先释放输入的 Solana 结算。

Remaining accounts

这些账户通过 .remainingAccounts(...) 追加在具名账户之后;它们的数量取决于订单,因此不是固定的 IDL 账户。下文中,N 为输出或载荷数量,A 为认证,R 为其存储的租金退还接收方。所有 remaining account 条目都不是签名者。 对于托管的结算和退款,远程认证以及以其他消费方为消费方的本地认证不会被消费。它们的 A 账户可以是只读的,其 R 槽位必须提供但会被忽略——任何已存在的只读账户(例如 system program)都可以占用被忽略的槽位。永远不要省略它。对于会被消费的认证,请传入真实存储的租金接收方。可执行的接收方会推迟租金回收,但仍需要其可写的账户元数据。重复的地址保留各自的位置;Solana 会在编译交易时合并重复密钥的权限。 例如,一个包含两个载荷的 submit_consume:

事件与错误

每个 IDL 都列出了其程序发出的事件。Wormhole IDL 包含由共享预言机代码发出的 OutputProvenEvent;它的鉴别器和字段顺序与 Polymer 一致:先是 u128 类型的链 ID,然后是三个 32 字节字段(远程标识符、application、载荷哈希)。 每个程序 IDL 只列出其本地错误。共享错误——以及它所调用的程序的错误——位于 errors.json 中,按枚举名组织,每项包含 Rust 源路径、数字错误码、名称和消息。其 programs 映射按程序 ID 列出本地目录,以及该程序可能返回的共享或 CPI 目录。 解码一次失败时,请先从调用日志中确认实际失败的程序,然后在该程序的本地目录和共享目录中查找数字错误码。如果日志中有明确的 Anchor 错误名称和消息,请以其为准。在对 intents_protocol 的 CPI 中发生的失败使用其目录。即使数字重叠,也永远不要用这些错误码去标注未知或外部程序的错误;Anchor 框架错误和外部 CPI 错误需要各自的解码器。某个目录与某个程序相关联,并不意味着每个变体都能从每条指令触发。Anchor 默认的错误解码器不会读取 errors.json——请自行加载它。你最可能遇到的错误列在在 Solana 上调试中。

来源

该包描述的是 Solana 程序代码仓库 776773a 提交下的五个生产程序,使用 Anchor 0.31.1 构建。provenance.json 记录了完整的提交、源代码与原始 IDL 指纹、所应用的每一项修正,以及每个已发布文件的哈希。这些修正只改变客户端元数据——移除 pda 提示并补充 Wormhole 事件——从不改变账户、标志、参数或链上约束。已发布的审计报告覆盖的是经过审查的合约版本;IDL 工具链是之后的集成改动。

TypeScript 类型

与每个 IDL 对应的驼峰式 TypeScript 类型,供 Anchor 的 Program<T> 使用。请把每个类型保存为 JSON 文件旁边的 types/<program>.ts。每个类型都精确描述对应的 JSON IDL;如果你自行重新生成 IDL,请从同一次构建中重新生成类型。
input_settler_escrow.ts
output_settler_simple.ts
polymer.ts
intents_protocol.ts
wormhole.ts

后续步骤

Solana 程序

每个程序的职责及其账户模型

在 Solana 上调试

解读失败的交易和错误码