Это руководство демонстрирует, как построить гибкую систему мониторинга, которая может отслеживать любое on-chain событие, обрабатывать данные транзакций и доставлять уведомления в реальном времени через webhook. Объединяя мощные критерии триггеров системы Alert Tenderly с Web3 Actions, вы создадите модульную инфраструктуру мониторинга, способную адаптироваться под любые потребности мониторинга блокчейна — от простого отслеживания событий до сложных мультиконтрактных взаимодействий.
В этом руководстве предполагается, что у вас есть аккаунт Tenderly и базовое знакомство с Web3 Actions и событиями блокчейна.
Модульный мониторинг с Web3 Actions
Предварительные требования
Перед началом убедитесь, что у вас есть:
- Node.js (в настоящее время в качестве последней версии поддерживается v20)
- Установленный Tenderly CLI
- Конечная точка webhook для получения данных
- Базовое понимание TypeScript
Настройка системы
Тип оповещения (Alert Type): мы настроим его как Successful Transaction. Подробные шаги можно найти здесь
Цель оповещения (Alert Target): в качестве цели мы используем Tag, который позволяет отслеживать все контракты и кошельки, помеченные конкретным тегом. Здесь можно посмотреть, как добавить Tag для контракта или кошелька.
Параметр оповещения (Alert Parameter): выберите Tag из выпадающего списка, содержащий контракты, которые мы хотим отслеживать
Назначение оповещения (Alert Destination): пока вы можете настроить что угодно, на следующем этапе мы настроим Web3 Action как назначение для этого оповещения
Клонируйте репозиторий. Ссылку на шаблон можно найти здесь
После клонирования репозитория выполните следующую команду в CLI:
cd actions && npm install
Настройка переменных окружения
Установите эти
Secrets в вашем Tenderly Web3 Action:
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 должен выглядеть так:
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 аккаунта, который можно получить, следуя этому руководству.
PROJECT_SLUG: ваш slug проекта, который можно получить, следуя этому руководству.
YOUR_ALERT_ID: ID оповещения, которое вы создали на предыдущем шаге. ID можно найти в панели.
Разверните ваш Web3 Action
Запустите следующую команду для развёртывания вашего Web3 Action:
Основные компоненты
Обработка транзакции
Система начинает с обработки информации о транзакции:
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.
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);
}
};
Обработка событий
Обработка событий выполняется с помощью специализированных функций:
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:
{
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
}
Устранение неполадок
Распространённые проблемы и решения:
-
Пропущенные события
- Убедитесь, что EVENT_NAME точно соответствует событиям контракта
- Проверьте конфигурацию оповещения в панели Tenderly
- Просмотрите логи транзакции на предмет генерации события
-
Ошибки API
- Проверьте права токена BEARER
- Проверьте доступность endpoint API
- Проверьте настройки сети
-
Проблемы с webhook
- Убедитесь в доступности WEBHOOK_URL
- Проверьте, что формат полезной нагрузки соответствует ожиданиям
- Отслеживайте логи endpoint’а webhook