> ## Documentation Index
> Fetch the complete documentation index at: https://injectivelabs-docs-ai-sdk.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Web3 Gateway 交易

*前置阅读 #1:* [交易生命周期](https://docs.cosmos.network/main/basics/tx-lifecycle)

*前置阅读 #2:* Injective 上的交易

Web3Gateway 微服务向最终用户暴露一个 API，其主要目的是为 Injective 上发生的交易提供费用委托。这允许用户在与 Injective 交互时享受无 gas 环境，因为 gas 由 Web3Gateway 服务的运行者支付。

除了费用委托支持外，Web3Gateway 还允许开发者将消息转换为 EIP712 类型数据。将消息转换为 EIP712 数据后，可以由任何 Ethereum 原生钱包签名，然后广播到 Injective。

## 费用委托

如前所述，费用委托允许用户与 Injective 交互（提交交易）而无需支付 gas。作为每个 Cosmos-SDK 驱动链的\_交易生命周期\_的一部分，我们有 `AnteHandler`，它们除其他事项外执行签名验证、gas 计算和费用扣除。

有几件事我们需要知道：

* 交易可以有多个签名者（即我们可以在交易中包含多个签名），
* 交易的 Gas 费用从 `authInfo.fee.feePayer` 值中扣除，针对 `feePayer` 验证的签名是交易签名列表中的第一个签名（[参考](https://github.com/cosmos/cosmos-sdk/blob/e2d6cbdeb55555893ffde3f2ae0ed6db7179fd0d/x/auth/ante/fee.go#L15-L24)），
* 其余签名针对交易的实际发送者进行验证。

知道这一点，为了实现费用委托，我们必须使用 Web3Gateway 微服务的私钥签名交易，将该 `privateKey` 的地址作为 `feePayer` 包含在内，使用我们想要与 Injective 交互的 privateKey 签名此交易，然后广播该交易。

## Web3Gateway API

每个人都可以运行 Web3Gateway 微服务并为其用户提供费用委托服务。一个示例用法是在 Injective 上构建交易所 dApp 的开发者运行此微服务，为其交易者提供无 gas 交易环境。

此微服务暴露一个包含两个核心方法的 API：

* `PrepareTx`（和 `PrepareCosmosTx`）
* `BroadcastTx`（和 `BroadcastCosmosTx`）

## PrepareTx

`PrepareTx` 方法接受一个消息（或多个消息），包括用户想要执行的交易的上下文（`chainId`、`signerAddress`、`timeoutHeight` 等），并返回特定消息的 EIP712 类型数据，包括 EIP712 类型数据中的签名。我们可以使用此 EIP712 类型数据使用任何 Ethereum 原生钱包签名它，并获取想要与 Injective 交互的用户的签名。

EIP712 类型数据是从我们传递给 `PrepareTx` 方法的消息的 proto 定义生成的。

## BroadcastTx

`BroadcastTx` 方法负责将交易广播到节点。除了 `PrepareTx` API 调用的完整响应外，我们还传入 EIP712 类型数据的签名。然后，`BroadcastTx` 将消息打包到原生 Cosmos 交易中，准备交易（包括其上下文）并将其广播到 Injective。结果是将交易哈希返回给用户。

## Prepare/BroadcastCosmosTx

当我们使用 **Ethereum 原生钱包**签名和广播交易时使用上述方法，因为我们签名的是 EIP712 交易表示。

如果我们想使用 Web3Gateway 在 Cosmos 原生钱包上支持费用委托，我们可以省略 PrepareCosmosTx 调用（或者如果我们需要 Web3Gateway 签名者的 `publicKey` 则调用它），在客户端准备交易，使用 Cosmos 钱包签名它，并使用 `BroadcastCosmosTx` 方法广播它。

其工作方式是我们将 `Web3Gateway` 签名者的 `publicKey` 添加到 `TxRaw` 中的 `authInfo` 对象，然后在广播时在 API 端使用 `privateKey` 签名交易。

<Callout icon="info" color="#07C1FF" iconType="regular">
  与之前的 EIP712 方法的区别在于，我们需要提前使用 `Web3Gateway` 的签名者签名交易，即当我们生成 EIP712 时 → 这意味着我们需要使用 `PrepareTx` 并且不能在客户端生成交易。
</Callout>
