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

# Модульный мониторинг с Web3 Actions

> Постройте модульную систему мониторинга с помощью Web3 Actions и Alerts для отслеживания on-chain событий, обработки трейсов и доставки уведомлений через webhook.

Это руководство демонстрирует, как построить гибкую систему мониторинга, которая может отслеживать любое on-chain событие, обрабатывать данные транзакций и доставлять уведомления в реальном времени через webhook. Объединяя мощные критерии триггеров системы Alert Tenderly с Web3 Actions, вы создадите модульную инфраструктуру мониторинга, способную адаптироваться под любые потребности мониторинга блокчейна — от простого отслеживания событий до сложных мультиконтрактных взаимодействий.

<Note>
  В этом руководстве предполагается, что у вас есть аккаунт Tenderly и базовое знакомство с Web3 Actions и событиями блокчейна.
</Note>

<Card title="Модульный мониторинг с Web3 Actions" href="" />

## Предварительные требования

Перед началом убедитесь, что у вас есть:

* [Node.js](https://nodejs.org/) (в настоящее время в качестве последней версии поддерживается **v20**)
* Установленный [Tenderly CLI](https://github.com/Tenderly/tenderly-cli)
* Конечная точка webhook для получения данных
* Базовое понимание TypeScript

## Настройка системы

<Steps>
  ### Создание Alert

  * **Тип оповещения (Alert Type):** мы настроим его как **Successful Transaction**. Подробные шаги можно найти [здесь](/monitoring/alerts/types#successful-transaction)

  <Frame caption="Настройка оповещения Successful Transaction">
    <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/alerts/successful-transaction-alert-setup.png?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=1cdcf8993e7e2c3103b75373ba50a5f3" alt="Setup Successful Transaction Alert" width="2754" height="1744" data-path="images/alerts/successful-transaction-alert-setup.png" />
  </Frame>

  * **Цель оповещения (Alert Target):** в качестве цели мы используем **Tag**, который позволяет отслеживать все контракты и кошельки, помеченные конкретным тегом. Здесь можно посмотреть, как добавить **Tag** для [контракта](/developer-explorer/contracts#adding-tags-to-contracts) или [кошелька](/developer-explorer/wallets#adding-tags-to-wallets).

  <Frame caption="Настройка Tag в качестве цели оповещения">
    <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/alerts/alert-tag-as-target.png?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=fd6734ef878ea316cfa0878a83b7a928" alt="Setup Tag as an Alert Target" width="2740" height="1354" data-path="images/alerts/alert-tag-as-target.png" />
  </Frame>

  * **Параметр оповещения (Alert Parameter):** выберите **Tag** из выпадающего списка, содержащий контракты, которые мы хотим отслеживать

  <Frame caption="Выберите тег, который вы хотите использовать">
    <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/alerts/tag-as-alert-parameter.png?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=3f01512085b5a49b93b69e81a5315212" alt="Choose Tag you want to use" width="2742" height="1194" data-path="images/alerts/tag-as-alert-parameter.png" />
  </Frame>

  * **Назначение оповещения (Alert Destination):** пока вы можете настроить что угодно, на следующем этапе мы настроим Web3 Action как назначение для этого оповещения

  ### Установка зависимостей

  * Клонируйте репозиторий. Ссылку на шаблон можно найти [здесь](https://github.com/Tenderly/flexible-monitoring-solution)

  * После клонирования репозитория выполните следующую команду в CLI:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  cd actions && npm install
  ```

  ### Настройка переменных окружения

  Установите эти [Secrets](/monitoring/web3-actions/references/context#secrets) в вашем Tenderly Web3 Action:

  ```env showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  WEBHOOK_URL = <Your webhook URL>
  BEARER = <Your Tenderly API bearer token>
  ACCOUNT_SLUG = <Your Tenderly account slug>
  PROJECT_SLUG = <Your project slug>
  EVENT_NAME = <Name of the event to track>
  ```

  ### Настройка tenderly.yaml

  Ваш `tenderly.yaml` должен выглядеть так:

  ```yaml showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  account_id: "<YOUR_ACCOUNT_ID>"
  actions:
    <YOUR_ACCOUNT_ID>/<PROJECT_SLUG>:
      runtime: v2
      sources: actions
      specs:
        example:
          description: "Event tracking system"
          function: example:modularFn
          trigger:
            type: alert
            alert: { <YOUR_ALERT_ID> }
          execution_type: parallel
  project_slug: "<PROJECT_SLUG>"
  ```

  Обязательно замените плейсхолдеры следующими значениями:

  * `YOUR_ACCOUNT_ID`: ваш ID аккаунта, который можно получить, следуя [этому руководству](/platform/account/projects/slug).
  * `PROJECT_SLUG`: ваш slug проекта, который можно получить, следуя [этому руководству](/platform/account/projects/slug).
  * `YOUR_ALERT_ID`: ID оповещения, которое вы создали на предыдущем шаге. ID можно найти в панели.

  <Frame caption="Поиск ID оповещения">
    <img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/alerts/alert-id.png?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=b637e922e730f0e99a5c3c45ea9de811" alt="Finding the Alert ID" width="2942" height="2090" data-path="images/alerts/alert-id.png" />
  </Frame>

  ### Разверните ваш Web3 Action

  Запустите следующую команду для развёртывания вашего Web3 Action:

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  tenderly actions deploy
  ```
</Steps>

## Основные компоненты

### Обработка транзакции

Система начинает с обработки информации о транзакции:

```typescript showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
export const modularFn = async (context: Context, transactionEvent: TransactionEvent) => {
  const txHash = transactionEvent.hash;
  const txNetwork = transactionEvent.network;

  const blockHash = transactionEvent.blockHash;
  const blockNumber = transactionEvent.blockNumber;

  const WEBHOOK_URL = await context.secrets.get("WEBHOOK_URL");
  const BEARER = await context.secrets.get("BEARER");
  const ACCOUNT_SLUG = await context.secrets.get("ACCOUNT_SLUG");
  const PROJECT_SLUG = await context.secrets.get("PROJECT_SLUG");
  const EVENT_NAME = await context.secrets.get("EVENT_NAME");

  if (!EVENT_NAME) {
    throw new Error("EVENT_NAME not found in environment variables");
  }

  const url = `https://api.tenderly.co/api/v1/public-contract/${txNetwork}/trace/${txHash}`;

  const traceResponse = await axios.get(url, {
    headers: {
      authorization: BEARER,
    },
  });

  const traceData = traceResponse.data;
```

Этот компонент:

* Захватывает хеш транзакции и сеть
* Получает трейсы транзакции через Tenderly API
* Обрабатывает информацию о блоке

### Получение информации о контракте

Информация о контракте (имена и ABI) получается с помощью [Contracts API](/api-reference).

```typescript showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const fetchContractName = async (addr: string) => {
  const contractEndpoint = `https://api.tenderly.co/api/v1/account/${ACCOUNT_SLUG}/project/${PROJECT_SLUG}/contract/${txNetwork}/${addr}`;

  try {
    const contractResponse = await axios.get(contractEndpoint, {headers: {'Authorization': BEARER}});
    return contractResponse.data.contract.contract_name;
  } catch (error) {
    console.error(`Error fetching contract name from endpoint for ${addr}:`, error);
  }
};

const fetchContractAbi = async (addr: string) => {
  const contractEndpoint = `https://api.tenderly.co/api/v1/account/${ACCOUNT_SLUG}/project/${PROJECT_SLUG}/contract/${txNetwork}/${addr}`;

  try {
    const contractResponse = await axios.get(contractEndpoint, {headers: {'Authorization': BEARER}});
    return contractResponse.data.contract.data.abi;
  } catch (error) {
    console.error(`Error fetching contract ABI from endpoint for ${addr}:`, error);
  }
};
```

### Обработка событий

Обработка событий выполняется с помощью специализированных функций:

```typescript showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
const extractEventAddresses = (logs: any[]): string[] =>
  Array.from(new Set(
    logs
      .filter(log => log.name === EVENT_NAME)
      .map(log => log.raw.address)
  ));

const extractEventDetails = (logs: any[]) => {
  return logs
    .filter(log => log.name === EVENT_NAME)
    .map(log => {
      const result: { [key: string]: string } = {
        name: log.name
      };

    log.inputs.forEach((input: any) => {
      const name = input.soltype.name;
      const value = input.value.toString();
      result[name] = value;
    });

    return result;
  });
};
```

Этот раздел:

* Фильтрует события по имени
* Извлекает параметры события
* Обрабатывает адреса событий

## Взаимодействие с webhook

Система отправляет эти структурированные данные на ваш webhook с помощью Axios:

```typescript showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
{
  hash: string,              // Transaction hash
  transaction: object,       // Full transaction event
  blockHash: string,        // Block hash
  blockNumber: number,      // Block number
  matchReasons: Array<{     // Event details
    name: string,
    [parameterName: string]: string
  }>,
  sentinel: {               // Contract information
    contractName: string,
    abi: object
  },
  traceData: object,        // Transaction trace data
  addresses: string[]       // Involved addresses
}
```

## Устранение неполадок

Распространённые проблемы и решения:

1. **Пропущенные события**
   * Убедитесь, что EVENT\_NAME точно соответствует событиям контракта
   * Проверьте конфигурацию оповещения в панели Tenderly
   * Просмотрите логи транзакции на предмет генерации события

2. **Ошибки API**
   * Проверьте права токена BEARER
   * Проверьте доступность endpoint API
   * Проверьте настройки сети

3. **Проблемы с webhook**
   * Убедитесь в доступности WEBHOOK\_URL
   * Проверьте, что формат полезной нагрузки соответствует ожиданиям
   * Отслеживайте логи endpoint'а webhook
