Skip to main content
校验、降级、模拟和编译各自强制执行前三页所引入的规则:Flow 形态、资源模型和 ref 语法。
Flow 是声明式的:它描述交易应该做什么,而不是如何生成字节码。POST /compose 会将 Flow JSON 转化为你的钱包可以签名的 transactionRequest。本页描述用户可观测的行为:服务会检查什么、模拟什么、返回什么。

当你调用 POST /compose 时会发生什么

1

Shape validation

Flow JSON 会针对线格式(wire-format)schema 进行校验:必填字段、类型和 ref 形态。格式错误的输入会在其他任何处理之前以 decode_error(HTTP 400)被拒绝。
2

Semantic validation

每个 op 和 guard 名称都必须已注册,每个绑定的 port 都必须存在并与其预期 kind(resource 还是 handle)匹配,且每个 ref 都必须能解析到同一 flow 中声明的某个节点或输入。失败会以 validation_errorlinearity_errorresolve_error 的形式暴露出来。
3

Runtime input resolution

你传入的 run.inputs 值会针对 Flow 声明的输入进行解析。普通整数或十六进制字符串会被原样使用;而 materialiser 描述符(例如 directDepositbalanceOf)会被展开为具体数量以及执行时需要成立的任何前置条件。参见 materialisers catalog
4

Amount preparation (when needed)

当某个节点依赖一个只能通过读取链上状态才能得知的值(例如某个 vault 的当前份额价格)时,服务会在生成 calldata 之前,从当前链上状态解析这些数量。
5

Lowering to executable bytecode

每个高层 op(例如 lifi.swaplifi.zap)都会被降级为 VM 实际执行的路由和转账调用。Guards 会附加到它们所保护的节点上。如果路由层无法为某条 zap 边找到路径,则会抛出 no_route_error
6

Sweeping

当设置了 run.sweepTo 时,会追加转账操作,将每一个终端资源(flow 运行后由执行 proxy 持有的代币)转移到请求的地址。sweep 目标通常是 builder.context.sender
7

Simulation and compilation (in parallel)

编译后的程序会同时被针对当前链上状态进行模拟,并被编译为 EVM calldata:
  • 模拟会针对目标链的最新状态(当前链头)运行该交易,检查每一个附加的 guard(例如最小输出、滑点),并为每个终端资源记录模拟得出的输出数量。违规会产生 guard_error;底层回滚会产生 simulation_revert
  • 编译会生成最终 calldata,并根据服务的策略(合约白名单、转账模式、指令数上限和外部调用分析)确认所产出的构件。
8

Price-impact check (optional)

当你传入 run.maxPriceImpactBps 且服务对输入和输出都有 USD 价格时,它会以 USD 汇总影响,并在超出该边界时以 price_impact_exceeded 拒绝编译。
9

Response

响应是一个 ComposeCompileResult —— 一个基于其 status 字段的可辨识联合类型(discriminated union)
  • status: 'success'(HTTP 200):编译干净地完成。载荷携带 transactionRequest(calldata、tovalue、可选的 gasLimit)、userProxy(执行地址)、producedResources(终端资源记录的映射;模拟数量位于 .simulated.amountOut / .simulated.amountOutMin 下)、任何所需的 approvals,以及可选的价格影响明细。
  • status: 'partial'(HTTP 206,仅当 run 上设置了 simulationPolicy: "allow-revert" 时):编译生成了 transactionRequest,但模拟回滚了。载荷会额外携带 error{ kind, message })和 simulationRevert,以便调用方能够呈现回滚原因,而不是隐藏它。
在读取特定于形态的字段之前,请先基于 result.status 分支 —— 在一次 allow-revert 调用之后,不检查 status 就访问 result.transactionRequest 是可行的,但忽略 simulationRevert 会隐藏你专门选择接收的那个信号。

你可能会看到的错误

服务会返回一个带有 kind 字段的结构化 ComposeError。最常见的 kind: 如果你传入 simulationPolicy: "allow-revert",一个结构化回滚会以 HTTP 206 Partial Content 返回,同时携带该交易以及回滚诊断信息,而不是让调用失败。当你希望向用户呈现回滚原因而非隐藏它时,这会很有用。

另请参阅