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

# 用 Tenderly 模拟 Safe{Wallet} 交易

> 在 Safe Wallet 的 Environment variables 中填写 Tenderly API URL 和令牌，用自己的项目模拟 Safe 交易。

Safe\{Wallet} 通过 [Tenderly Simulation API](/simulations/single-simulations#simulate-via-api) 模拟交易。内置模拟功能属于 Safe Pro。在其他 Safe 计划中，Safe Shield 中的 **Transaction simulation** 检查会显示 **Set** 链接，队列中的交易会显示 **Set up simulation**，而不是模拟结果。要在任何 Safe 计划中运行模拟，请在 Safe 的 **Environment variables** 设置中添加您自己的 Tenderly 项目。之后 Safe 会将每个模拟请求发送到您的项目，每次模拟都会连同完整的调用追踪保存在该项目中。

<Note>
  生成 API 访问令牌以及使用 Tenderly API 需要付费计划。要为您的账户启用这些功能，请[联系我们的销售团队](https://tenderly.co/contact-us)预约通话并讨论升级您的计划。
</Note>

## 前提条件

* 一个 Tenderly 项目。
* 一个可访问该项目的[访问令牌](/platform/account/projects/api-tokens)。项目令牌（**One project** 范围）即可。
* 一个 Safe 账户，且您连接的钱包是其所有者。

## 构建 Tenderly API URL

**Tenderly API URL** 字段需要填写完整的 Simulation API 端点，包括 `/simulate` 路径：

```bash title="Tenderly API URL" theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
https://api.tenderly.co/api/v1/account/{account_slug}/project/{project_slug}/simulate
```

在 Tenderly 中打开您的项目，进入 **Settings**，点击 **Project Access Tokens** 旁边的 **Copy API URL**，然后在复制的 URL 末尾加上 `simulate`。例如，账户为 `my-org`、项目为 `treasury` 时，结果为 `https://api.tenderly.co/api/v1/account/my-org/project/treasury/simulate`。

<Warning>
  **Copy API URL** 复制的是项目的基础 URL，以 `/project/{project_slug}/` 结尾。Safe 会将请求发送到您输入的确切 URL，因此使用不带 `simulate` 的基础 URL 会导致每次模拟都失败。
</Warning>

## 在 Safe\{Wallet} 设置中添加 Tenderly 项目

1. 在 Safe\{Wallet} 中打开 **Settings**，选择 **Environment variables** 标签页。**Set** 和 **Set up simulation** 链接也会打开此页面。
2. 在 **Tenderly** 下，将上一节中的 URL 粘贴到 **Tenderly API URL**。
3. 将访问令牌粘贴到 **Tenderly access token**。
4. 点击 **Save**。Safe 会重新加载页面并应用设置。

<Frame caption="Safe{Wallet} Environment variables 中的 Tenderly API URL 和访问令牌">
  <img src="https://mintcdn.com/tenderly/oghi1Zo4upwEdT7R/images/simulations/safe-wallet/environment-variables-tenderly.webp?fit=max&auto=format&n=oghi1Zo4upwEdT7R&q=85&s=92d9bd7e5aa09cb189d58f62c53814be" alt="Safe{Wallet} Environment variables 设置：以 /simulate 结尾的 Tenderly API URL 和已隐藏的访问令牌" width="1190" height="456" data-path="images/simulations/safe-wallet/environment-variables-tenderly.webp" />
</Frame>

请填写两个字段。只有 URL 和访问令牌都已设置时，Safe 才会使用您的项目。

Safe 将这些值存储在浏览器的本地存储中。它们适用于您在该浏览器中打开的所有 Safe 和网络，因此请在您使用的每个浏览器中重复此设置。要恢复默认值，请点击每个字段中的重置图标，然后点击 **Save**。

## 运行 Safe 交易模拟

1. 在 Safe\{Wallet} 中点击 **New transaction**，设置交易后点击 **Next**。**Confirm transaction** 页面随即打开，右侧显示 Safe Shield 面板。
2. 点击 **Transaction simulation** 旁边的 **Run**。
3. 检查结果会变为 **Simulation successful** 或 **Simulation failed**。点击 **View** 即可在您的 Tenderly 项目中打开该模拟。

<Frame caption="显示模拟成功和 View 链接的 Safe Shield">
  <img src="https://mintcdn.com/tenderly/oghi1Zo4upwEdT7R/images/simulations/safe-wallet/safe-shield-simulation-successful.webp?fit=max&auto=format&n=oghi1Zo4upwEdT7R&q=85&s=fe0fcdb115367bdb0712987e9dd501be" alt="Safe{Wallet} 的 Confirm transaction 页面，Safe Shield 显示 Simulation successful 和 View 链接" width="1040" height="420" data-path="images/simulations/safe-wallet/safe-shield-simulation-successful.webp" />
</Frame>

要模拟已在队列中的交易，请打开 **Transactions**，在 **Queue** 标签页中展开该交易，然后点击 **Simulate**。

**View** 链接会打开 `https://dashboard.tenderly.co/{account_slug}/{project_slug}/simulator/{simulation_id}`，您可以在其中查看所模拟的 `execTransaction` 调用的[调用追踪、状态变化和事件](/simulator-ui/overview)。

## Safe 向 Simulation API 发送的内容

Safe 向 Tenderly API URL 发送 `POST` 请求，并在 `X-Access-Key` 请求头中携带访问令牌。请求体是对 Safe 的 `execTransaction` 调用（批量交易则为 `multiSend` 调用）的[单笔模拟](/simulations/single-simulations)，设置如下：

| 字段 | 值 |
| - | - |
| `from` | 如果您连接的钱包是所有者，则为该钱包，否则为 Safe 的第一个所有者 |
| `gas_price` | `0`，因此发送方无需持有 gas 余额 |
| `save`、`save_if_fails` | `true`：每次模拟都会保存到您的项目，包括失败的模拟 |
| `state_objects` | 针对 Safe 合约的[状态覆盖](/simulations/state-overrides)：缺少签名时将阈值设为 `1`；交易不是队列中的下一笔时，将 nonce 设为该交易的 nonce；如设置了交易 guard，则将其移除 |

## 故障排除：Error while simulating

当 Simulation API 返回错误时，Safe 会在交易队列中显示 **Error while simulating**，在 Safe Shield 中显示 **Simulation failed**，但不显示错误详情。要查看实际响应：

1. 打开浏览器的开发者工具，选择 **Network** 标签页。
2. 再次运行模拟。
3. 选择发送到 `api.tenderly.co` 的请求，查看其状态码和响应体。

| 响应 | 原因 | 解决方法 |
| - | - | - |
| `400` `validation`：`at least one of name, options, restricted or members must be provided` | URL 是不带 `simulate` 的项目基础 URL | 按照[构建 Tenderly API URL](#构建-tenderly-api-url)在 URL 末尾加上 `simulate` |
| `401` `unauthorized` 或 `403` `insufficient_permissions` | 访问令牌已撤销、已过期或输入有误 | [创建新的访问令牌](/platform/account/projects/api-tokens)并粘贴到 Safe 中 |
| `404` `Project not found` | 项目 slug 错误，或令牌无权访问该项目 | 使用 **Copy API URL** 重新复制 URL，并检查令牌的范围 |
| `404` `Platform Account not found` | 账户 slug 错误 | 使用 **Copy API URL** 重新复制 URL |
| CORS 错误 | URL 指向 `dashboard.tenderly.co` 而不是 `api.tenderly.co` | 使用[构建 Tenderly API URL](#构建-tenderly-api-url)中的 API URL |
| `200` 且 `simulation.status: false` | 模拟已运行，但交易会回滚（revert） | 点击 **View**，在 [Debugger](/debugger/overview) 中查看回滚原因 |

如果没有请求到达 `api.tenderly.co`，请确认两个字段都已保存：在 URL 和访问令牌都设置之前，Safe 会一直显示 **Set** 链接。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.