> ## 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.

# Сухой прогон пользовательских транзакций

> Узнайте, как интегрировать Simulation API, чтобы делать сухой прогон транзакций пользователей и помогать им избегать финансовых потерь, разочарования и тревоги при использовании вашего dapp'а.

## Обзор

Узнайте, как использовать [Simulation API](/simulations/overview) в вашем dapp'е, чтобы позволить пользователям предварительно просматривать результаты транзакций перед их отправкой в сеть. Так вы сможете помочь им избежать финансовых потерь из-за неудачных или некорректных транзакций и повысить их уверенность при использовании вашего dapp'а.

Чтобы интегрировать Simulation API от Tenderly в ваш dapp для обнаружения потенциальных сбоев транзакции ещё до её отправки в сеть, вам нужно:

1. Сформировать сырые транзакции из библиотеки ethers.js.
2. Симулировать транзакции перед их отправкой.
3. (опционально) Обернуть каждое взаимодействие с блокчейном в симуляцию Tenderly.

Подробности запроса и ответа для отдельного вызова см. в разделе [одиночные симуляции](/simulations/single-simulations).

### Формирование сырых транзакций из ethers.js

Первый шаг — создать объект транзакции, который будет отправлен в наш эндпоинт симуляции. Мы сгенерируем его непосредственно из библиотеки `ethers.js`. В приведённом ниже примере показано, как это можно сделать для функции `transfer()` поверх контракта DAI:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const dai = new ethers.Contract(DAI_ADDRESS, DAI_ABI, tenderlyForkProvider);

const unsignedTx = await dai.populateTransaction.transfer(
  ZERO_ADDRESS,
  YOUR_ADDRESS,
  util.ether(1),
);
```

### Симуляция транзакций перед отправкой

Теперь, когда мы извлекли неподписанную сырую транзакцию, давайте симулируем её перед отправкой в сеть (в Ethereum Mainnet):

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
...

const body = {
    "network_id": "1",
    "from": senderAddr,
    "to": contract.address,
    "input": unsignedTx.data,
    "gas": 21204,
    "gas_price": "0",
    "value": 0,
    "save_if_fails": true
}

const headers = {
    headers: {
        'content-type': 'application/JSON',
        'X-Access-Key': TENDERLY_ACCESS_KEY,
  }
}
const resp = await axios.post(apiURL, body, headers);

if (resp.data.simulation.status === false) {
	// it failed, do as you please
}
```

### Оборачивание каждого взаимодействия с блокчейном в симуляцию Tenderly (опционально)

Чтобы гарантировать, что каждое взаимодействие с блокчейном сначала симулируется, напишите простую обёртку вокруг объекта signer из `ethers.js`, которая всегда будет симулировать транзакции.

Кроме того, в дальнейшем вы можете ввести типизированные ошибки, с которыми может взаимодействовать ваша логика:

```tsx title="example.tsx" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
export class TenderlySimulationSigner {
  public _provider: ethers.Provider;

  constructor(provider: ethers.Provider) {
    this._provider = provider;
  }

  public async sendTransaction(
    transaction: Deferrable<TransactionRequest>,
  ): Promise<TransactionResponse> {
    await this._simulateTx(transaction);

    return this._signer.sendTransaction(transaction);
  }

  public async getAddress(): Promise<string> {
    return this._signer.getAddress();
  }

  public async signTransaction(transaction: Deferrable<TransactionRequest>): Promise<string> {
    return this._signer.signTransaction(transaction);
  }

  _simulateTx(transaction: Deferrable<TransactionRequest>): Promise<void> {
    const unsignedTx = await contract.populateTransaction[funcName](...args);

    const apiURL = `https://api.tenderly.co/api/v1/account/me/project/project/simulate`;
    const body = {
      network_id: '1',
      from: senderAddr,
      to: contract.address,
      input: unsignedTx.data,
      gas: 21204,
      gas_price: '0',
      value: 0,
      save_if_fails: true,
    };

    const headers = {
      headers: {
        'content-type': 'application/JSON',
        'X-Access-Key': REACT_APP_TENDERLY_ACCESS_KEY as string,
      },
    };
    const resp = await axios.post(apiURL, body, headers);
    if (resp.data.simulation.status == false) {
      throw new Error('Transaction is going to fail');
    }

    return;
  }
}
```

<Info>
  Вот [репозиторий на
  GitHub](https://github.com/Tenderly/integration-samples/tree/main/dry-run-transactions), где
  вы можете найти пример этой реализации.
</Info>
