gasCosts 和 feeCosts。它们回答的是不同的问题,计价方式也不同,且都不能简单地对应到”用户在每条链上要支付多少”这个问题上。本指南说明如何读取这两个数组,以便你向用户展示准确的成本明细。
成本数组存放在哪里
这两个数组都挂在一个estimate 对象下,而 estimate 属于某个步骤。并不是每个响应都会直接把步骤交给你。
路由是其所含步骤的一个外层封装,本身没有
estimate。读取 route.estimate 会得到 undefined。路由顶层唯一携带的成本数值是 gasCostUSD,一个单一的汇总字符串。
这两个数组都是可选的。一个步骤可能两者都没有,或者返回一个空数组,这属于有效报价,而不是报价失败。每次读取前都要先做好判空处理。
gasCosts 还是 feeCosts?
区分依据是谁提交交易,而不是这笔钱花在什么用途上。
某项成本是”为了 gas”产生的,并不意味着它就归入
gasCosts。例如一个 bridge 为目标链执行付费并将其计入用户账单,这会记录为一个 feeCosts 条目,因为用户从未签署过目标链上的交易。
读取一条 gas 成本
price 的单位是 gas 代币的最小单位(每单位 gas),也就是说在 EVM 链上是 wei/gas,而不是 gwei。对于 EVM 条目,amount 等于 estimate * price,limit 等于 estimate 加上一个缓冲量。其他生态可能采用链特有的单位和取整方式,因此应以返回的 amount 为准,而不要自行重新计算。在基于这些字段构造 EVM 交易时,请使用 limit,而不是 estimate。
Gas 成本类型
GasCost.type 定义了四种可能的取值,但目前实际生产环境中只使用其中一种。
如果出现
APPROVE、FEE 或 SUM,请妥善处理它们,以保持你的集成面向未来兼容,但不要围绕它们构建依赖它们出现的流程。如果你现在就需要授权操作的 gas 成本,请自行针对 approvalAddress 进行估算。一项成本属于哪条链?
token.chainId 告诉你的是某项成本以哪条链的代币计价,而不是底层的实际工作发生在哪条链上。
对 gasCosts 而言,二者是一致的:gas 是以消耗它的那条链的原生代币支付的,因此 token.chainId 就是执行所在的链。
对 feeCosts 而言,二者往往并不一致。以下面这个报价为例:50 USDC 从以太坊发送,兑换为 Base 上的 cbBTC:
chainId: 1 理解为”这是一项源链成本”是应当避免的误读。
目标链执行成本体现在哪里
LI.FI 并不保证一定会分别返回源链和目标链两项独立的 gas 条目。根据所用工具的不同,目标链执行成本会以三种方式之一体现给你:- 作为一条
feeCosts条目,通常命名为类似Relayer Gas fee或Network fee,以源链代币计价。这是最常见的情况。 - 作为工具特有的数据,例如
estimate.data内的一个destinationGasConsumption值。具体结构因工具而异。 - 已计入输出金额,没有单独的条目。报价中的
toAmount已经扣除了这部分成本。
Relayer Gas fee、Relayer gas fee 和 Network fee 在不同工具中都存在。可以向用户展示 name 和 description,但不要基于它们做分支判断。
用户是否需要原生 gas?
答案取决于由谁广播源链交易,因此要从你所集成的执行模式说起。
在这两种模式下,目标链通常都不需要原生 gas。目标链上的执行由 LI.FI 或 bridge 完成,任何相关成本都会体现在
feeCosts 中,或已计入 toAmount。
无 gas 功能的可用性在报价时确定。目前它要求源链是 EVM 链,且账户是 LI.FI 支持的 EIP-7702 委托账户;并非所有链、委托合约或账户类型都符合条件。当前的要求和执行流程详见 无 gas 交易。
如果你的集成采用自行提交方式,请在让用户签名之前,将源链原生余额与 gasCosts[].amount 进行比对。一个持有足够 USDC 但没有 ETH 的用户会在提交阶段失败,而不是在报价阶段。如果你采用中继方式,这项检查就不适用于用户,此时 gasCosts 条目描述的是中继器要花费的成本,而不是用户需要持有的余额。
旧版中继路径所需的签名格式详见 Permit 与 Permit2 授权流程。
目标链场景有一个值得规划的例外情况:用户携带已桥接的代币到达一条新链,但没有原生余额,因而无法进行下一步操作。这是一个冷启动问题,而不是执行问题,LI.Fuel 正是为解决它而存在的。
LI.Fuel 不是执行 gas
fromAmountForGas 会将所发送金额的一部分兑换为目标链的原生代币,并随桥接资产一并交付给用户。它的作用是让用户拥有下一步操作所需的 gas。
在构建成本明细时,请将两者区分开:
- 执行 gas 是完成这笔转账所需的成本,体现在
gasCosts和feeCosts中。 - LI.Fuel 是用户主动要求以原生代币形式收到的一笔额外金额,它会减少
toAmount,并不属于这笔转账的成本。
included 标志
included 决定了某项费用是否已经反映在报价金额中。
included: true表示该费用已经计入,报价中的toAmount已经是扣除后的净值。可以在明细中展示它,但不要再作为一笔独立的用户支付项重复计入。included: false表示用户需要在fromAmount之外额外支付这笔费用。
included: true 的费用再叠加计入一次,是集成中最常见的、导致向用户展示的成本被高估的原因。
不要把顶层数组和步骤级数组相加
一个lifi 步骤自带其 estimate.feeCosts 和 estimate.gasCosts,includedSteps 中的每个条目也各自携带自己的成本。顶层数组是从步骤级数组推导出来的,因此把两者相加会导致重复计算。
它们的推导方式并不相同,这一点很重要:
feeCosts在顶层是所有被包含步骤的费用成本的拼接结果。条目和金额均相同。gasCosts在顶层是针对实际提交的那一笔交易的单一估算值。它会汇总源链上各被包含步骤的原始 gas 成本,并针对 EVM 交易额外加上预估的 LI.FI 合约开销。因此它可能与——通常会高于——源链各步骤条目金额的简单求和不同。目标链被包含步骤的原始 gas 成本不会被直接相加进来。
在这个例子中,费用一列的数字相符,而 gas 一列不相符,因为顶层数值覆盖的是用户实际提交的那唯一一笔交易,其中包含了 LI.FI 合约开销。
后续步骤
Gas Fronting
使用
fromAmountForGas 向用户交付目标链原生代币。费用与变现
集成商费用如何配置和收取。
报价 API 参考
完整的响应结构,包括
estimate、feeCosts 和 gasCosts。路由与报价的区别
何时调用
/quote,何时调用 /advanced/routes。
