Skip to main content
既然你已经知道被传递的是什么(resources、handles),本页将介绍把它们接线到一起的 dotpath 语法。
ref 是一个包裹在 { "$ref": "…" } 中的 dotpath 字符串。Ref 让某个 Call 能够将它的某个输入 port 绑定到 Flow 中别处产生的值:一个声明的输入、前一个 call 的输出,或一个运行时上下文值。 该语法识别种作用域,并保留少量前缀以避免歧义。

三种 ref 作用域

1. input.<name>

引用在 flow.inputs 中声明的一个 flow 级输入。
解析为 { scope: "input", port: "amountIn" }

2. context.<key>

引用一个运行时上下文值。目前仅识别两个键:
解析为 { scope: "context", key: "sender" }context.* 下的任何其他键都会被拒绝。

3. <nodeId>.<port>

任何前缀不是 inputcontext 的 ref 都会被视为对另一个 call 的输出 port 的引用。<nodeId> 是你添加该节点时传入的用户自定义 id(例如,builder.lifi.swap('swap', …) 会产生形如 swap.<port> 的 refs)。
解析为 { scope: "output", node: "swap", port: "amountOut" }

保留前缀

有三个前缀是保留的,不能用作节点 id:inputcontextliteral。Flow 校验会拒绝 id 与其中任何一个匹配的节点。 literal 不是 ref 作用域;它被保留是为了让语法保持无歧义。字面通过一种独立机制表达,即 LiteralBinding,它与 refs 一起存在于节点的 bind 记录中:

SDK handles 如何变成 refs

合作伙伴代码通常不会直接构造 refs。SDK 为你提供 handles(由 builder 返回的类型化 JavaScript 值),并在序列化 call 时将它们转换为 refs。 Handles 有三种形态:
  • InputHandlebuilder.inputs.<name> 返回。序列化为 input.<name>
  • ResourceInputHandle InputHandle 的一个子类型,用于 resource input,携带资源声明。
  • OutputHandle 由 op 调用返回。builder.lifi.swap('swap', …).amountOut 序列化为 swap.amountOut(其中 swap 是你作为第一个参数传入的用户自定义节点 id)。
转换是自动的。你把 handles 传入 bind,SDK 就会生成正确的 $ref 字符串。上下文 refs 通过 builder.context 暴露:
  • builder.context.sender{ $ref: "context.sender" }
  • builder.context.executionAddress{ $ref: "context.executionAddress" }

原始 refs(应急出口)

当你需要引用一个你通过 builder.untypedOp(...) 创建的 call 的输出,或引用类型化 API 未涵盖的路径时,使用 raw.ref<T>(path) 来获得一个可被 Bindable<T> 槽位接受的类型化 TypedRef
raw.ref 不做运行时校验;调用方负责选择正确的类型参数。

小结

  • 存在三种作用域:input.<name>context.<sender|executionAddress><nodeId>.<port>
  • <name><nodeId> 是用户自定义的:你在编写 flow 时挑选它们。
  • literal 是一个保留前缀,而不是 ref 作用域。字面值使用 LiteralBinding,而不是 ref。
  • SDK handles 会自动转换为 refs。你几乎不需要手写 ref 字符串。
  • 仅当类型化 API 无法表达你所需的 ref 时,才使用 raw.ref<T>(path)
一旦 Flow 接线完成,你就把它 POST 到 /compose。下一页 Execution Model 介绍这条流水线。