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

# Оповещения в Discord о новых пулах Uniswap

> Следуйте пошаговому руководству, чтобы создать Web3 Action, который будет отправлять вам сообщение в Discord всякий раз, когда создаётся новый пул Uniswap V3.

Этот туториал показывает, **как использовать [Web3 Action](/monitoring/web3-actions/introduction) для отправки сообщения в канал Discord при создании нового пула на Uniswap V3**. Вы можете использовать этот Web3 Action для уведомления сообщества, когда в цепочке происходит что-то важное.

<Note>
  Полный код доступен в [**этом Github-репозитории**](https://github.com/Tenderly/examples-web3-actions/). Обратите внимание, что на данный момент он находится в отдельной ветке.
</Note>

## Обзор проекта

Цель этого проекта — научить вас использовать Web3 Actions для отправки сообщения в Discord всякий раз, когда создаётся пул Uniswap. Мы покажем два подхода: более удобный — использовать событие `PoolCreated` как триггер для нашего Web3 Action (см. [функции, события и триггеры](/monitoring/web3-actions/references/functions-events-triggers) и [**документацию Uniswap**](https://developers.uniswap.org/protocol/V2/reference/smart-contracts/factory#paircreated)).

## План

* Добавьте контракты в свой проект Tenderly — [**UniswapV3ContractFactory**](https://dashboard.tenderly.co/nenad/uniswap/contract/mainnet/0x1f98431c8ad98523631ae4a59f267346ea31f984). Он уже верифицирован и присутствует в Tenderly, поэтому вам просто нужно добавить его в свой проект.
* Сохраните URL webhook Discord в Secrets вашего Web3 Action.
* Создайте Web3 Action, который будет реагировать на событие `[PoolCreated](<https://developers.uniswap.org/protocol/reference/core/interfaces/IUniswapV3Factory#poolcreated>)`.

### 1: Добавьте контракты Uniswap в ваш проект Tenderly

Web3 Actions требуют, чтобы смарт-контракты, используемые для задания триггеров, были верифицированы в Tenderly.

Web3 Actions требуют, чтобы смарт-контракты, используемые для задания триггеров, были верифицированы в Tenderly. Поскольку мы используем существующие контракты, вы можете найти их через строку поиска, введя имя или адрес контракта.

Как вариант, перейдите на [**UniswapV2ContractFactory**](https://dashboard.tenderly.co/contract/mainnet/0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f) и нажмите **«Add to Project»**. Сделайте то же для [**UniswapV2Pair**](https://dashboard.tenderly.co/contract/mainnet/0xd849b2af570ffa3033973ea11be6e01b7ba661d9).

### 2: Создайте Web3 Action для события PoolCreated

Ниже вы найдёте код нашего Web3 Action, а также объяснение, как он работает:

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


export const onPoolCreatedEventEmitted: ActionFn = async (context: Context, event: Event) => {
  try {
    const txEvent = event as TransactionEvent;

    const eventLog = await getPoolCreatedEvent(txEvent);

    const tokensData = await getTokensData(eventLog.token0, eventLog.token1);
    console.log('Received Tokens Data: ', tokensData);

    await notifyDiscord(`${tokensData.token0.name} ↔️ ${tokensData.token1.name}`, context);
  } catch (error) {
    console.error(error);
  }
};

const getPoolCreatedEvent = async (txEvent: TransactionEvent) => {
  const ifc = new ethers.utils.Interface(UniswapV3FactoryAbi);
  const poolCreatedTopic = ifc.getEventTopic('PoolCreated');

  const poolCreatedEventLog = txEvent.logs.find(log => {
    return log.topics.find(topic => topic == poolCreatedTopic) !== undefined;
  });

  if (poolCreatedEventLog == undefined) {
    throw Error('PoolCreatedEvent missing');
  }
  return ifc.decodeEventLog(
    'PoolCreated',
    poolCreatedEventLog.data,
    poolCreatedEventLog.topics,
  ) as unknown as UniswapPool;
};

const getTokensData = async (token0: string, token1: string) => {
  const tokenFields = `id, name, symbol, totalValueLocked, totalSupply, derivedETH`;
  const theGraphQuery = `
{
	token0: token(id:"${token0.toLowerCase()}"){${tokenFields}},
	token1: token(id:"${token1.toLowerCase()}"){${tokenFields}}
}`;

  const UNISWAP_THE_GRAPH = 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3';
  const resp = await axios.post(UNISWAP_THE_GRAPH, {
    query: theGraphQuery,
  });

  return resp.data.data as unknown as {
    token0: UniwswapToken;
    token1: UniwswapToken;
  };
};

const notifyDiscord = async (text: string, context: Context) => {
  console.log('Sending to Discord:', `🐥 ${text}`);
  const webhookLink = await context.secrets.get('discord.uniswapChannelWebhook');
  await axios.post(
    webhookLink,
    {
      content: `🐥 ${text}`,
    },
    {
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
    },
  );
};

type UniswapPool = {
  token0: string;
  token1: string;
  fee: number;
  tickSpacing: number;
  pool: number;
};

type UniwswapToken = {
  id: string;
  name: string;
  symbol: string;
  tokenValueLocked: number;
  totalSupply: number;
  derivedEth: number;
};
```

**Получите токены во вновь созданном пуле.** Чтобы получить информацию о двух токенах в новом пуле, нам нужно поискать по логам транзакции в функции `getEventLog`. Мы используем Ethers и ABI контракта: `UniswapV3FactoryAbi`. Перейдите к [**контракту `UniswapV3Factory` в Tenderly**](https://dashboard.tenderly.co/nenad/uniswap/contract/mainnet/0x1f98431c8ad98523631ae4a59f267346ea31f984), нажмите **«View ABI»** и скопируйте его в локальный файл в каталоге `actions`.

По сути, мы ищем запись лога в topic `PoolCreate`. Сначала берём ссылку на этот topic (`poolCreatedTopic = ifc.getEventTopic("PoolCreated")`), а затем фильтруем сами логи (`tx.logs`), пока не найдём запись, ссылающуюся на этот topic. Наконец, декодируем найденный лог (`poolCreatedEventLog`) с помощью Ethers. Это то самое событие, которое мы ищем, и оно содержит адреса токенов: `token0` и `token1`.

**Получите данные о токенах через Graph API Uniswap на TheGraph.** Uniswap предоставляет доступ к своим данным через [**TheGraph**](https://thegraph.com/hosted-service/subgraph/uniswap/uniswap-v3). Мы используем функцию `getTokensData`, чтобы обратиться к TheGraph и получить несколько полей для ID `token0` и `token1` — тех, что присутствуют в событии `PoolCreated` из первого шага.

**Уведомите сообщество Discord.** Собрав всю необходимую информацию, мы готовы отправить сообщение в наш канал Discord. С функцией `notifyDiscord` нам нужно получить URL webhook из `secrets`. Мы используем Axios, чтобы сделать HTTP-запрос POST и запустить webhook, передав ему содержимое.

### 3: Настройте ваш Web3 Action

В файле `tenderly.yaml` нам нужно указать, что мы хотим запускать `uniswapActions:onPoolCreatedEventEmitted` при генерации события контрактом `UniswapV3Factory` (по адресу `0xd849b2af570ffa3033973ea11be6e01b7ba661d9`) в транзакции, заминированной в Mainnet (network 1).

```yaml title="example.yaml" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
account_id: ''
actions:
  YOUR_USERNAME/YOUR_PROJECT_SLUG:
    runtime: v1
    sources: actions
    specs:
      uniswapNewPool:
        description: Runs when a new swap is made on Uniswap
        function: uniswapActions:onPoolCreatedEventEmitted
        trigger:
          type: transaction
          transaction:
            status:
              - mined
            filters:
              - network: 1
                eventEmitted:
                  contract:
                    address: 0xd849b2af570ffa3033973ea11be6e01b7ba661d9
                  name: PoolCreated
project_slug: ''
```

### 4: Сохраните URL webhook Discord в Secrets

Прежде чем запускать наш Web3 Action в Tenderly, необходимо задать значение для webhook Discord.

В Tenderly Dashboard перейдите на страницу Actions вашего проекта и нажмите Secrets. Добавьте новый секрет с именем `discord.uniswapChannelWebhook` и вставьте webhook вашего канала Discord.

### 5: Разверните и опробуйте ваш Web3 Action

Разверните ваш Web3 Action, выполнив эту команду:

```yaml title="example.yaml" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
tenderly actions deploy
```

**Чтобы проверить, работает ли ваш Web3 Action, перейдите на страницу Actions в Tenderly Dashboard. Выберите ваш action и нажмите Manual Trigger.**

Вот и всё! Надеемся, вы получили сообщение в своём канале Discord 🎉
