Выберите, на какую активность по транзакциям должно реагировать приложение и когда получать уведомления. В руководстве разобраны типизированные события и условия отправки уведомлений (trigger), включая разницу между обнаружением транзакции и её подтверждением.
4 вида для EVM и Tron 4 вида стейкинга Tron 1 вид для Bitcoin 1 триггер на подписку
Транзакция - это контейнер: она может перемещать ценность, выдавать разрешения и вызывать контракт. Сетевая комиссия может быть нулевой; coinbase-транзакция Bitcoin комиссию не платит. Vilna разбирает перемещения ценности, выдачу разрешений и вызовы контрактов на типизированные события; комиссия остаётся на самой транзакции, а не внутри какого-либо события.
вызов контракта
выдано одобрение
перемещение средств
Каждое событие несёт два поля, общих для всех видов, и дополнительные поля, специфичные для вида:
event_index- позиция внутри транзакции, с нуля, чтобы вы всегда знали порядок, в котором произошли события.kind- тип события:transfer,approval,interaction,contract_creation, один из четырёх видов стейкинга Tron или биткоиновыйutxo_transfer.
Поля, специфичные для вида, лежат прямо на объекте события - обёртки data нет. Событие transfer, например, несёт event_index, kind, asset_gid, amount, operation, from_address и to_address на одном уровне. Пример приведён ниже.
Сетевая комиссия - не одно из этих событий, а соседнее поле на транзакции, details.fee.
Какие виды событий несёт транзакция, зависит от её семейства сетей. EVM и Tron делят четыре вида; Tron добавляет к ним ещё четыре вида стейкинга; у Bitcoin ровно один.
Полные схемы вариантов событий находятся в ответе получения транзакции. Примеры ниже поясняют смысл каждого вида.
Активы перемещены с одного адреса на другой.
{
"event_index": 0,
"kind": "transfer",
"asset_gid": "eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7",
"amount": { "base": "1000000", "formatted": "1.0" },
"operation": "transfer",
"from_address": "0x742d35cc6634c0532925a3b8d1e1d78d8E15e5c4",
"to_address": "0x95212290dd7278aa3ddd389cc1e1d165cc4bafe5"
}Пользователь отправляет 1 USDT на кошелёк продавца. Событие transfer несёт отправителя, получателя, актив и точную сумму - ваша система обнаружения депозитов сопоставляет получателя с клиентом.
Выдано или изменено разрешение на расходование токена.
{
"event_index": 0,
"kind": "approval",
"asset_gid": "eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7",
"owner_address": "0x742d35cc6634c0532925a3b8d1e1d78d8E15e5c4",
"spender_address": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",
"allowance": { "base": "1000000000", "formatted": "1000.0" }
}Кто-то получает право перемещать токены с отслеживаемого адреса. Система, следящая только за переводами, молчит, пока токены не ушли; событие approval - раннее предупреждение. Отмечайте безлимитные или необычно большие разрешения для проверки.
Вызван смарт-контракт, с результатом вызова.
{
"event_index": 0,
"kind": "interaction",
"target_address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"caller_address": "0x742d35cc6634c0532925a3b8d1e1d78d8E15e5c4",
"outcome": "succeeded"
}Отслеживаемый адрес взаимодействует с контрактом, даже когда токены напрямую не двигаются. Событие interaction фиксирует вызов и его результат - полезно для выявления фишинга и полного аудита. Результат reverted значит, что вызов откатился - ничего из того, что он пытался сделать, не вступило в силу.
Развёрнут новый смарт-контракт.
{
"event_index": 0,
"kind": "contract_creation",
"creator_address": "0x742d35cc6634c0532925a3b8d1e1d78d8E15e5c4",
"created_address": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
}Отслеживаемый адрес разворачивает контракт. Событие фиксирует, кто его развернул и где он теперь находится - полезно для журнала соответствия требованиям.
TRX заблокированы под сетевой ресурс.
{
"event_index": 0,
"kind": "stake",
"owner_address": "TJRabPrwbZy45sbavfcjinPJC18kjpRTv8",
"amount": { "base": "1000000000", "formatted": "1000.0" },
"resource": "energy"
}Аккаунт блокирует TRX, чтобы получить сетевой ресурс. Событие stake называет ресурс - bandwidth, energy или право голоса - и заблокированную сумму.
Стейк возвращается владельцу.
{
"event_index": 0,
"kind": "unstake",
"owner_address": "TJRabPrwbZy45sbavfcjinPJC18kjpRTv8",
"amount": { "base": "1000000000", "formatted": "1000.0" },
"resource": "energy"
}Аккаунт запрашивает застейканные TRX обратно. Событие unstake фиксирует ресурс и сумму, которая освобождается; сами средства возвращаются позже, когда сработает отдельное событие stake_withdrawal.
TRX из созревшего анстейка стали доступны для расходования.
{
"event_index": 0,
"kind": "stake_withdrawal",
"owner_address": "TJRabPrwbZy45sbavfcjinPJC18kjpRTv8",
"amount": { "base": "1000000000", "formatted": "1000.0" }
}TRX из созревшего анстейка снова становятся доступны для расходования. Событие stake_withdrawal отмечает момент, когда средства фактически возвращаются владельцу.
Отменён ожидающий анстейк.
{
"event_index": 0,
"kind": "unstake_cancellation",
"owner_address": "TJRabPrwbZy45sbavfcjinPJC18kjpRTv8",
"amount": { "base": "1000000000", "formatted": "1000.0" },
"resource": "energy"
}Ожидающий анстейк отменяется до того, как созреет, и сумма возвращается в активный стейк. Событие unstake_cancellation фиксирует ресурс и сумму.
UTXO-перевод с полной видимостью входов и выходов - используется в Bitcoin вместо transfer.
{
"event_index": 0,
"kind": "utxo_transfer",
"asset_gid": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"is_coinbase": false,
"inputs": [{
"input_index": 0,
"previous_txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"previous_output_index": 1,
"amount": { "base": "150000", "formatted": "0.0015" }
}],
"outputs": [
{ "output_index": 0, "amount": { "base": "100000", "formatted": "0.001" } },
{ "output_index": 1, "amount": { "base": "45000", "formatted": "0.00045" } }
]
}При проверке происхождения средств (AML) важны все источники поступления. Одно событие utxo_transfer перечисляет каждый вход и выход для такой проверки. У coinbase-транзакции - собственной субсидии блока - нет входов вовсе; это отмечает is_coinbase.
События approval, interaction и contract_creation показывают разрешения, вызовы и развёртывание контрактов вместе с переводами. Это помогает связать действия одной транзакции:
Один обмен токенов (swap) на децентрализованной бирже может включать четыре события. Взгляд «только переводы» поймает два движения токенов, но упустит interaction, который их запустил, и approval, который дал роутеру право расходовать:
пользователь вызывает роутер свопа
роутеру выдано разрешение
входной токен уходит в пул
выходной токен уходит пользователю
У семейств сетей разные возможности. Вот что Vilna формирует для каждого - актуальный полный список всегда доступен через GET /blockchains.
| Возможность | EVM | TRON | Bitcoin |
|---|---|---|---|
transfer | Нативные + ERC-20 | Нативные + TRC-20 | Нет |
approval | ERC-20 | TRC-20 | Нет |
interaction | Вызовы контрактов | Вызовы контрактов | Нет |
contract_creation | Развёртывание | Развёртывание | Нет |
stake | Нет | Стейк ресурса | Нет |
unstake | Нет | Анстейк ресурса | Нет |
stake_withdrawal | Нет | Возврат созревших средств | Нет |
unstake_cancellation | Нет | Отмена ожидающего анстейка | Нет |
utxo_transfer | Нет | Нет | Полные входы/выходы |
Bitcoin использует utxo_transfer вместо transfer, раскрывая каждый вход и выход - смарт-контрактов в нём нет, поэтому approval, interaction и contract_creation не применяются. Четыре вида стейкинга специфичны для ресурсной модели Tron.
Solana регистрирует адреса и распознаёт токены, без транзакций и событий.
Подписка отправляет уведомление при выполнении выбранного условия (trigger). Она не уведомляет автоматически в два отдельных момента. Фильтры выбирают подходящие транзакции, а trigger определяет момент уведомления.
Триггер block срабатывает через фиксированное число блоков после включения. after_blocks: 0 означает «замечено», без гарантии необратимости.
Триггер network срабатывает при выполнении условий подтверждения для выбранной сети; точный порог Vilna не публикует.
Триггер mempool срабатывает до включения в блок, только для Bitcoin. Исключение для повторного уведомления описано ниже.
Подписка выбирает ровно один вид триггера при создании и сохраняет его навсегда; изменить позже, через PATCH, можно только значение after_blocks у триггера block, и такое изменение пересчитывает все ещё не сработавшие ожидания. Нужен ранний сигнал и более поздний сигнал подтверждения? Создайте две подписки с разными триггерами, а не ждите обоих от одной.
Создайте подписку через Создание подписки: выберите канал, семейство и один триггер. Для уведомления сразу после включения в блок используйте block с after_blocks: 0. Изменения допустимого порога описаны в Изменение подписки. На страницах операций находятся схемы и примеры запросов. Сохраните отдельный Idempotency-Key и исходные параметры; при потере ответа повторяйте их без изменений. См. правила повторов.
Подписка создаёт не больше одного уведомления на транзакцию; попыток его доставки может быть несколько. Повторное включение, изменившийся хеш блока или более позднее уточнение содержимого никогда не повторяют и не исправляют уже отправленное уведомление. Единственное исключение - подписка mempool: она может уведомить второй раз, если транзакция пропала из мемпула больше чем на час и затем появилась снова.
Триггер block означает включение в блок с заданной глубиной, network - выполнение политики подтверждения сети. Доставка webhook означает только доставку сообщения и не подтверждает оплату счёта. Для счёта перечитывайте status, received_amount, confirmed_amount и связи с транзакциями.
Уведомления об откате нет. Если транзакция, о которой вам сообщили, позже выпадает из цепочки, повторного сообщения не будет - для уверенности сверяйтесь через API.
Каждая подписка несёт is_noise_filtered, по умолчанию включённый. При включённом фильтре уведомление приходит, только когда сам отслеживаемый адрес действует - как отправитель, вызывающий, создатель или владелец, - либо когда движется нативный актив, либо токен, который проверен (is_verified) или доверен вашим проектом (is_trusted). Чужой адрес, перемещающий незнакомый токен через ваш адрес, остаётся без уведомления. Какие токены считаются проверенными или доверенными и как добавить свой - в руководстве о токенах.
Отключение is_noise_filtered снимает только это правило: уведомление приходит на любую подходящую активность, включая незнакомые токены. Это не отмечает токен как доверенный и не запускает отслеживание его баланса. В любом случае уведомление всегда несёт транзакцию целиком, а не только ту часть, что его вызвала.
Подписка обрабатывает транзакции только с момента своего создания; уведомления по прошлым транзакциям не создаются. Изменение фильтров, тегов или статуса доверия действует только на транзакции, оцениваемые после изменения; ничего уже поставленного в очередь или доставленного оно не затрагивает.
Отключение подписки отменяет её незавершённые ожидания. Повторное включение их не возобновляет - оно лишь возобновляет обработку новых транзакций.
При payload_version: v2 уведомление содержит WebhookV2Payload. Для декодированных действий читайте item.details.events, для изменений по адресам - item.activity, для названий и метаданных - references. Общая структура уведомления, схемы и проверка подписи описаны в справочнике Webhooks. Версию тела уведомления выбирают независимо от версии HTTP API.
О механике надёжного обработчика - быстро отвечать, проверять X-Webhook-Signature, отсеивать повторные уведомления по event_id - см. справочник Webhooks. После проверки подписи тела уведомления, работайте с моделью событий напрямую.
После проверки подписи выберите события по kind: transfer описывает перевод EVM/Tron, utxo_transfer - входы и выходы Bitcoin. Разрешайте метаданные по точному asset_gid в references.tokens; для расчётов сохраняйте точность base. Для сверки актуальных фактов используйте Получение транзакции, а для изменений по адресам - Список активности.
Создание каналов и пересылка уведомлений в другие системы описаны в разделе Каналы уведомлений.
Уведомления отправляются в порядке событий, но доставка не строго упорядочена - медленный получатель может получить более позднее событие раньше, чем завершится повтор более раннего. Разделяйте транзакции по chain_gid, затем упорядочивайте события по details.block.block_height, details.transaction_index и event_index. Когда блока нет, как в уведомлении из мемпула Bitcoin, item.created_at показывает только порядок наблюдения, а не порядок в блокчейне. Время ответа, расписание повторов и авто-отключение канала описаны в справочнике Webhooks.