> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Gas 成本与费用成本

> 如何读取报价中的 gasCosts 和 feeCosts，每项成本属于哪条链，以及用户何时需要原生 gas

成本以两个数组返回：`gasCosts` 和 `feeCosts`。它们回答的是不同的问题，计价方式也不同，且都不能简单地对应到"用户在每条链上要支付多少"这个问题上。本指南说明如何读取这两个数组，以便你向用户展示准确的成本明细。

***

## 成本数组存放在哪里

这两个数组都挂在一个 `estimate` 对象下，而 `estimate` 属于某个**步骤**。并不是每个响应都会直接把步骤交给你。

| 响应                                                         | 成本所在位置                                           |
| :--------------------------------------------------------- | :----------------------------------------------- |
| `/v1/quote`、`/v1/quote/toAmount`、`/v1/quote/contractCalls` | 返回步骤上的 `estimate.gasCosts` 和 `estimate.feeCosts` |
| `/v1/advanced/routes`                                      | 路由中每个步骤的 `routes[].steps[].estimate`             |
| 任何带有 `includedSteps` 的步骤                                   | 每个被包含步骤上各自的 `estimate`，作为其上层步骤的成本明细              |

路由是其所含步骤的一个外层封装，本身没有 `estimate`。读取 `route.estimate` 会得到 `undefined`。路由顶层唯一携带的成本数值是 `gasCostUSD`，一个单一的汇总字符串。

<Note>
  这两个数组都是可选的。一个步骤可能两者都没有，或者返回一个空数组，这属于有效报价，而不是报价失败。每次读取前都要先做好判空处理。
</Note>

***

## gasCosts 还是 feeCosts？

区分依据是**谁提交交易**，而不是这笔钱花在什么用途上。

|         | `gasCosts`                              | `feeCosts`                           |
| :------ | :-------------------------------------- | :----------------------------------- |
| 是什么     | 发送方提交交易所需的预估网络 gas                      | 任何以费用形式收取、而不是由发送方作为网络 gas 支付的成本      |
| 计价单位    | 交易发送所在链的原生 gas 代币                       | 任意代币，通常是用户本来就在发送的那个代币                |
| 由谁支付    | 提交交易的一方，从其原生余额中支付，在 `fromAmount` 之外额外支付 | 从转账金额中扣除，或额外加收，取决于 `included`        |
| 典型条目    | 源链执行                                    | 集成商费用、LI.FI 费用、bridge 或求解器费用、目标链执行成本 |
| 需要检查的字段 | `type`                                  | `included`                           |

某项成本是"为了 gas"产生的，并不意味着它就归入 `gasCosts`。例如一个 bridge 为目标链执行付费并将其计入用户账单，这会记录为一个 `feeCosts` 条目，因为用户从未签署过目标链上的交易。

***

## 读取一条 gas 成本

```json theme={"system"}
{
  "type": "SEND",
  "price": "128468782",        // 每单位 gas 的 wei 数
  "estimate": "459000",        // 该交易消耗的 gas 单位数
  "limit": "596700",           // estimate 加上安全缓冲，提交交易时使用这个值
  "amount": "58967170938000",  // estimate * price，单位为 wei
  "amountUSD": "0.1156",
  "token": {
    "symbol": "ETH",
    "decimals": 18,
    "chainId": 1               // 消耗这笔 gas 的链
  }
}
```

`price` 的单位是 gas 代币的最小单位（每单位 gas），也就是说在 EVM 链上是 wei/gas，而不是 gwei。对于 EVM 条目，`amount` 等于 `estimate * price`，`limit` 等于 `estimate` 加上一个缓冲量。其他生态可能采用链特有的单位和取整方式，因此应以返回的 `amount` 为准，而不要自行重新计算。在基于这些字段构造 EVM 交易时，请使用 `limit`，而不是 `estimate`。

### Gas 成本类型

`GasCost.type` 定义了四种可能的取值，但目前实际生产环境中只使用其中一种。

| 类型        | 含义                         | 目前是否返回                  |
| :-------- | :------------------------- | :---------------------- |
| `SEND`    | 发送方提交交易所需的预估网络 gas，通常在源链上  | 是                       |
| `APPROVE` | 一笔独立 ERC-20 授权交易的预估网络 gas  | 否，授权 gas 目前不会作为独立条目返回   |
| `FEE`     | 以费用形式收取、而非作为用户签署的交易收取的执行成本 | 否，这类成本会出现在 `feeCosts` 中 |
| `SUM`     | 其他条目的汇总                    | 否                       |

<Note>
  如果出现 `APPROVE`、`FEE` 或 `SUM`，请妥善处理它们，以保持你的集成面向未来兼容，但不要围绕它们构建依赖它们出现的流程。如果你现在就需要授权操作的 gas 成本，请自行针对 `approvalAddress` 进行估算。
</Note>

***

## 一项成本属于哪条链？

`token.chainId` 告诉你的是某项成本**以哪条链的代币计价**，而不是底层的实际工作发生在哪条链上。

对 `gasCosts` 而言，二者是一致的：gas 是以消耗它的那条链的原生代币支付的，因此 `token.chainId` 就是执行所在的链。

对 `feeCosts` 而言，二者往往并不一致。以下面这个报价为例：50 USDC 从以太坊发送，兑换为 Base 上的 cbBTC：

```json theme={"system"}
{
  "name": "Relayer Gas fee",
  "description": "Relay bridge gas fee",
  "token": { "symbol": "USDC", "chainId": 1, "decimals": 6 },  // 以以太坊上的代币计价
  "amount": "1116",
  "amountUSD": "0.0011",
  "percentage": "0.0000",
  "included": true
}
```

这笔费用覆盖的是 Base 上的执行成本，但计价方式是以太坊上的 USDC，因为那正是用户本来就在发送的代币。把 `chainId: 1` 理解为"这是一项源链成本"是应当避免的误读。

<Warning>
  不要仅凭 `token.chainId` 推导出按链拆分的成本明细。如果你的界面需要说明"你在源链上支付 X，在目标链上支付 Y"，仅凭报价本身是无法可靠构建出这个结论的。
</Warning>

***

## 目标链执行成本体现在哪里

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 | 由谁支付                               |
| :----------------------------------------------------------------------------------------------- | :----------- | :--------------------------------- |
| 自行提交。用户签署一个 `transactionRequest` 并自行广播                                                           | 是            | 用户，从其原生余额中支付，在 `fromAmount` 之外额外支付 |
| 无 gas，适用于符合条件的 EVM 账户。用户对来自 `gasless=true` 报价的一个 EIP-712 载荷签名，LI.FI 通过 `/v1/advanced/relay` 代为中继 | 否            | LI.FI。中继成本通过 `feeCosts` 以输入代币计价回收  |
| 中继（旧方案）。用户签署一条 Permit2 消息，LI.FI 的中继器通过 `/v1/relayer/relay` 广播                                    | 否            | 中继器。成本通过 `feeCosts` 回收             |

在这两种模式下，目标链通常都不需要原生 gas。目标链上的执行由 LI.FI 或 bridge 完成，任何相关成本都会体现在 `feeCosts` 中，或已计入 `toAmount`。

无 gas 功能的可用性在报价时确定。目前它要求源链是 EVM 链，且账户是 LI.FI 支持的 EIP-7702 委托账户；并非所有链、委托合约或账户类型都符合条件。当前的要求和执行流程详见 [无 gas 交易](/guides/gasless-transactions)。

如果你的集成采用自行提交方式，请在让用户签名之前，将源链原生余额与 `gasCosts[].amount` 进行比对。一个持有足够 USDC 但没有 ETH 的用户会在提交阶段失败，而不是在报价阶段。如果你采用中继方式，这项检查就不适用于用户，此时 `gasCosts` 条目描述的是中继器要花费的成本，而不是用户需要持有的余额。

旧版中继路径所需的签名格式详见 [Permit 与 Permit2 授权流程](/introduction/user-flows-and-examples/permit2-approval-flow)。

目标链场景有一个值得规划的例外情况：用户携带已桥接的代币到达一条新链，但没有原生余额，因而无法进行下一步操作。这是一个冷启动问题，而不是执行问题，LI.Fuel 正是为解决它而存在的。

### LI.Fuel 不是执行 gas

`fromAmountForGas` 会将所发送金额的一部分兑换为目标链的原生代币，并随桥接资产一并交付给用户。它的作用是让用户拥有*下一步*操作所需的 gas。

在构建成本明细时，请将两者区分开：

* **执行 gas** 是完成这笔转账所需的成本，体现在 `gasCosts` 和 `feeCosts` 中。
* **LI.Fuel** 是用户主动要求以原生代币形式收到的一笔额外金额，它会减少 `toAmount`，并不属于这笔转账的成本。

相关请求参数及其限制详见 [Gas Fronting](/guides/gas-subsidy)。

***

## `included` 标志

`included` 决定了某项费用是否已经反映在报价金额中。

* `included: true` 表示该费用已经计入，报价中的 `toAmount` 已经是扣除后的净值。可以在明细中展示它，但不要再作为一笔独立的用户支付项重复计入。
* `included: false` 表示用户需要在 `fromAmount` 之外额外支付这笔费用。

把一项 `included: true` 的费用再叠加计入一次，是集成中最常见的、导致向用户展示的成本被高估的原因。

***

## 不要把顶层数组和步骤级数组相加

一个 `lifi` 步骤自带其 `estimate.feeCosts` 和 `estimate.gasCosts`，`includedSteps` 中的每个条目也各自携带自己的成本。顶层数组是从步骤级数组**推导**出来的，因此把两者相加会导致重复计算。

它们的推导方式并不相同，这一点很重要：

* **`feeCosts`** 在顶层是所有被包含步骤的费用成本的拼接结果。条目和金额均相同。
* **`gasCosts`** 在顶层是针对实际提交的那一笔交易的单一估算值。它会汇总源链上各被包含步骤的原始 gas 成本，并针对 EVM 交易额外加上预估的 LI.FI 合约开销。因此它可能与——通常会高于——源链各步骤条目金额的简单求和不同。目标链被包含步骤的原始 gas 成本不会被直接相加进来。

以上面那笔 50 USDC 的报价为例：

| 来源                         | Gas          | 费用           |
| :------------------------- | :----------- | :----------- |
| `includedSteps[0]`（费用收取）   | \$0.0327     | \$0.1249     |
| `includedSteps[1]`（bridge） | \$0.0217     | \$0.0549     |
| 各步骤求和                      | \$0.0544     | \$0.1798     |
| 顶层 `estimate`              | **\$0.1156** | **\$0.1798** |

在这个例子中，费用一列的数字相符，而 gas 一列不相符，因为顶层数值覆盖的是用户实际提交的那唯一一笔交易，其中包含了 LI.FI 合约开销。

<Warning>
  展示给用户或用于计费的任何金额，都应使用顶层 `estimate` 数组。将 `includedSteps` 中的成本视为用于调试和展示的明细，而不要作为需要额外相加的金额。
</Warning>

***

## 后续步骤

<CardGroup cols={2}>
  <Card title="Gas Fronting" icon="gas-pump" href="/guides/gas-subsidy">
    使用 `fromAmountForGas` 向用户交付目标链原生代币。
  </Card>

  <Card title="费用与变现" icon="coins" href="/faqs/fees-monetization">
    集成商费用如何配置和收取。
  </Card>

  <Card title="报价 API 参考" icon="code" href="/api-reference/get-a-quote-for-a-token-transfer">
    完整的响应结构，包括 `estimate`、`feeCosts` 和 `gasCosts`。
  </Card>

  <Card title="路由与报价的区别" icon="diagram-project" href="/introduction/user-flows-and-examples/difference-between-quote-and-route">
    何时调用 `/quote`，何时调用 `/advanced/routes`。
  </Card>
</CardGroup>
