Отслеживание трансфера
Предварительные шаги
Перед отслеживанием трансфера необходимо его отправить. См. Отправка трансфера для получения Transfer ID.
Transfer ID
Что это технически
Transfer ID — это transaction hash события на Proxy контракте.
┌─────────────────────────────────────────────────────────────────┐
│ Proxy Contract │
│ │
│ 1. Получает токены через transferNotification() │
│ 2. Вызывает _emitTvmEvent() или _deployEvmEvent() │
│ 3. Эмитит событие TvmTvmNative или TvmTvmAlien │
│ 4. Transaction hash этого события = TRANSFER ID │
└─────────────────────────────────────────────────────────────────┘Где в блокчейне находится
Transaction (на Proxy контракте) ← Transaction Hash = TRANSFER ID
├── In Message (входящие токены)
├── Out Messages
│ ├── Internal Messages (internal transfers)
│ └── External Out Message ← СОБЫТИЕ (TvmTvmNative/TvmTvmAlien)
└── Account (обновлённое состояние)Типы событий
| Событие | TokenType | Описание |
|---|---|---|
TvmTvmNative | Native | Трансфер native токена (lock → mint) |
TvmTvmAlien | Alien | Трансфер alien токена (burn → unlock) |
Статусы трансфера
Два уровня статусов
В системе существует два уровня статусов:
| Уровень | Где хранится | Назначение |
|---|---|---|
| TransferStatus | Bridge Aggregator API | Агрегированный статус для UI/интеграций |
| Event Contract Status | On-chain (Event контракт) | Детальное состояние верификации события |
Связь: Bridge Aggregator API агрегирует on-chain статусы Event контракта в упрощённый TransferStatus:
Event Contract Status → TransferStatus (API)
─────────────────────────────────────────────────────────────────────
Initializing, Pending, Verified → Pending
Confirmed, LiquidityProvided → Completed
Rejected, Cancelled → FailedTransferStatus (API level)
Используется в ответах Bridge Aggregator API (/v2/transfers/status, /v2/transfers/search).
| Статус | Код | Описание |
|---|---|---|
Pending | 1 | Событие создано, ожидает подтверждения в сети назначения |
Completed | 2 | Трансфер полностью завершён (токены доставлены) |
Failed | 3 | Трансфер отклонён релеями |
Event Contract Status (on-chain level)
Детальные статусы Event контракта в блокчейне. Используются для понимания на каком этапе верификации находится событие.
| Статус | Код | Описание | → TransferStatus |
|---|---|---|---|
Initializing | 0 | Event контракт задеплоен | Pending |
Pending | 1 | Ожидание верификации | Pending |
Confirmed | 2 | Подтверждён, proxy вызван, токены доставлены | Completed |
Rejected | 3 | Отклонён | Failed |
Cancelled | 4 | Отменён пользователем | Failed |
LimitReached | 5 | Превышен дневной лимит, требуется ликвидность | Pending |
LiquidityRequested | 6 | Запрос ликвидности создан | Pending |
LiquidityProvided | 7 | Ликвидность предоставлена, токены доставлены | Completed |
Verified | 8 | Merkle proof проверен, ожидание деплоя токенов | Pending |
Переход для trustless: Pending → Verified → Confirmed
Диаграмма переходов статусов
Получение статуса по Transfer ID
API Endpoint
POST https://tetra-history-api.chainconnect.com/v2/transfers/status
Content-Type: application/jsonТестовое окружение
Для тестирования используйте https://history-api-test.chainconnect.com/v2/transfers/status
Параметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
outgoingTransactionHash | string | ✅ | Transfer ID (hex, 64 символа) |
dappChainId | number | ✅ | Chain ID сети отправления (TON = -239, Tycho = 2000) |
timestampCreatedFrom | number | ❌ | Unix timestamp для фильтрации (опционально) |
Пример запроса (TvmTvm)
curl -X POST 'https://tetra-history-api.chainconnect.com/v2/transfers/status' \
-H 'Content-Type: application/json' \
-d '{
"tvmTvm": {
"outgoingTransactionHash": "abc123def456...",
"dappChainId": -239,
"timestampCreatedFrom": null
}
}'Пример ответа
{
"transfer": {
"tvmTvm": {
"transferStatus": "Pending",
"timestampCreatedAt": 1767972717,
"outgoing": {
"tokenType": "Native",
"chainId": -239,
"userAddress": "0:3333...cccc",
"tokenAddress": "0:1111...aaaa",
"proxyAddress": "0:6666...ffff",
"volumeExec": "0.1000",
"volumeUsdtExec": "0",
"feeVolumeExec": "0",
"messageHash": "abc123def456...",
"transactionHash": "def789abc012..."
},
"incoming": {
"tokenType": "Alien",
"chainId": 2000,
"userAddress": "0:2222...bbbb",
"tokenAddress": "",
"proxyAddress": "",
"volumeExec": "0",
"volumeUsdtExec": "0",
"feeVolumeExec": null,
"messageHash": "",
"transactionHash": null
}
}
},
"updatedAt": 1767972720,
"notInstantTransfer": null,
"proofPayload": {
"txBlockProof": "te6ccgECCg...",
"txProof": "te6ccgEBBw...",
"messageHash": "abc123def456...",
"outMessageIndex": 0,
"event": {
"tokenType": "Native",
"chainId": 2000,
"token": "0:1111...aaaa",
"amount": "99000",
"recipient": "0:2222...bbbb",
"value": "150000000",
"expectedGas": "0",
"remainingGasTo": "0:3333...cccc",
"sender": "0:3333...cccc",
"payload": "te6ccgEBAQEAAgAAAA==",
"nativeProxyWallet": "0:9999...2222",
"name": "Tether USD",
"symbol": "USD₮",
"decimals": 6
},
"abiTx": {
"tx": "te6ccgEBBwEA6AABiw/X8c8...",
"executionAddress": "0:8888...1111",
"attachedValue": "2000000000",
"abiMethod": "deployEvent",
"abi": "...",
"params": "{\"_eventVoteData\":{...}}"
}
}
}Описание полей ответа
transfer.tvmTvm — данные трансфера
| Поле | Тип | Описание |
|---|---|---|
transferStatus | string | Статус: "Pending", "Completed", "Failed" |
timestampCreatedAt | number | Unix timestamp создания трансфера |
outgoing — данные исходящей стороны
Все поля non-nullable. При отсутствии данных подставляются дефолты ("" для строк, "0" для чисел).
| Поле | Тип | Описание |
|---|---|---|
tokenType | string | "Native" или "Alien" |
chainId | number | Chain ID сети |
userAddress | string | Адрес отправителя |
tokenAddress | string | Адрес токена в сети отправления |
proxyAddress | string | Адрес proxy контракта |
volumeExec | string | Сумма в human-readable формате |
volumeUsdtExec | string | Сумма в USDT эквиваленте |
feeVolumeExec | string | Удержанная комиссия |
messageHash | string | Hash сообщения события |
transactionHash | string | Hash транзакции (= Transfer ID) |
incoming — данные входящей стороны
Большинство полей non-nullable (дефолты "" / "0" пока трансфер не завершён). Только feeVolumeExec и transactionHash nullable.
| Поле | Тип | Описание |
|---|---|---|
tokenType | string | "Native" или "Alien" |
chainId | number | Chain ID сети |
userAddress | string | Адрес получателя |
tokenAddress | string | Адрес токена в сети назначения (пустая строка, пока трансфер не завершён) |
proxyAddress | string | Адрес proxy контракта (пустая строка, пока трансфер не завершён) |
volumeExec | string | Сумма в human-readable формате ("0" пока не завершён) |
volumeUsdtExec | string | Сумма в USDT эквиваленте ("0" пока не завершён) |
feeVolumeExec | string | null | Удержанная комиссия |
messageHash | string | Hash сообщения события (пустая строка, пока не завершён) |
transactionHash | string | null | Hash транзакции доставки (null пока не завершён) |
proofPayload — данные для non-credit трансферов
| Поле | Тип | Описание |
|---|---|---|
txBlockProof | string | Proof блока (BOC base64) |
txProof | string | Merkle proof транзакции (BOC base64) |
messageHash | string | Hash сообщения события |
outMessageIndex | number | Индекс исходящего сообщения в транзакции |
event | object | Данные события (см. ниже) |
abiTx | object | null | Готовая транзакция для deployEvent (см. ниже) |
proofPayload.abiTx — готовая транзакция для non-credit
| Поле | Тип | Описание |
|---|---|---|
tx | string | Payload транзакции (BOC base64) |
executionAddress | string | Адрес EventConfiguration контракта |
attachedValue | string | Требуемый газ в nano-единицах |
abiMethod | string | Метод контракта (deployEvent) |
abi | string | ABI контракта |
params | string | Параметры вызова (JSON string) |
proofPayload.event — данные события
| Поле | Тип | Описание |
|---|---|---|
tokenType | string | "Native" или "Alien" |
chainId | number | Chain ID сети назначения |
token | string | Адрес токена |
amount | string | Сумма в nano-единицах |
recipient | string | Адрес получателя |
value | string | Прикреплённое значение (газ) |
expectedGas | string | Ожидаемый газ |
remainingGasTo | string | Адрес для возврата газа |
sender | string | Адрес отправителя |
payload | string | Дополнительный payload (BOC base64) |
nativeProxyWallet | string | null | Адрес wallet прокси (для Native) |
name | string | null | Название токена |
symbol | string | null | Символ токена |
decimals | number | null | Количество decimals |
notInstantTransfer — данные liquidity request
Не применимо для TVM↔TVM
Поле notInstantTransfer заполняется только для EVM-трансферов (TvmEvm, EvmEvm, TvmEvmTvm). Для TVM↔TVM трансферов это поле всегда null. Лимиты и недостаток ликвидности обрабатываются на уровне Event контракта — см. Обработка лимитов и Liquidity Requests.
Интерпретация ответа
| Поле | Значение | Действие |
|---|---|---|
transferStatus: "Pending" | Ожидание | Продолжить polling |
transferStatus: "Completed" | Завершён | Успех! |
transferStatus: "Failed" | Ошибка | Обработать ошибку |
proofPayload != null | Proof готов | Можно деплоить event (non-credit) |
incoming.transactionHash != null | Вторая часть выполнена | Трансфер почти завершён |
История трансферов
API Endpoint
POST https://tetra-history-api.chainconnect.com/v2/transfers/search
Content-Type: application/jsonПараметры запроса
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
userAddresses | string[] | ❌ | Фильтр по адресам пользователя (макс 7) |
transferKinds | string[] | ❌ | Тип трансфера: ["TvmToTvm"] |
statuses | string[] | ❌ | Фильтр по статусам: ["Pending", "Completed", "Failed"] |
fromTvmChainId | number | ❌ | Chain ID сети отправления |
toTvmChainId | number | ❌ | Chain ID сети назначения |
createdAtGe | number | ❌ | Unix timestamp >= (от какой даты) |
createdAtLe | number | ❌ | Unix timestamp <= (до какой даты) |
ordering | string | ❌ | Сортировка: "CreatedAtAscending" или "CreatedAtDescending" |
limit | number | ✅ | Лимит записей (макс количество в ответе) |
offset | number | ✅ | Смещение (для пагинации) |
isNeedTotalCount | boolean | ✅ | Возвращать ли общее количество трансферов |
Пример запроса
curl -X POST 'https://tetra-history-api.chainconnect.com/v2/transfers/search' \
-H 'Content-Type: application/json' \
-d '{
"userAddresses": ["0:3333...cccc"],
"transferKinds": ["TvmToTvm"],
"statuses": ["Pending", "Completed"],
"fromTvmChainId": -239,
"toTvmChainId": 2000,
"ordering": "CreatedAtDescending",
"limit": 10,
"offset": 0,
"isNeedTotalCount": true
}'Пример ответа
{
"transfers": [
{
"tvmTvm": {
"transferStatus": "Completed",
"timestampCreatedAt": 1767972717,
"outgoing": {
"tokenType": "Native",
"chainId": -239,
"userAddress": "0:3333...cccc",
"tokenAddress": "0:1111...aaaa",
"proxyAddress": "0:6666...ffff",
"volumeExec": "1.0000",
"transactionHash": "abc123..."
},
"incoming": {
"tokenType": "Alien",
"chainId": 2000,
"userAddress": "0:2222...bbbb",
"tokenAddress": "0:4444...dddd",
"proxyAddress": "0:7777...0000",
"volumeExec": "0.9990",
"transactionHash": "def456..."
}
}
}
],
"totalCount": 42
}Transfer ID для каждого трансфера: transfers[i].tvmTvm.outgoing.transactionHash
Алгоритм отслеживания
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. ПОЛУЧИТЬ TRANSFER ID │
│ После отправки токенов на Proxy контракт, сохранить transaction │
│ hash этой транзакции — это и есть Transfer ID │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 2. ЗАПРОСИТЬ СТАТУС │
│ POST /v2/transfers/status с Transfer ID и Chain ID │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 3. ПРОВЕРИТЬ transferStatus │
│ │
│ "Pending" → Трансфер в процессе, повторить запрос через 5-10 сек │
│ "Completed" → Успех! Токены доставлены получателю │
│ "Failed" → Ошибка, трансфер отклонён │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 4. ДЛЯ ЗАВЕРШЁННОГО ТРАНСФЕРА │
│ incoming.transactionHash — hash транзакции доставки токенов │
│ incoming.volumeExec — полученная сумма (после комиссий) │
└─────────────────────────────────────────────────────────────────────────┘Что проверять в ответе
| Поле | Что означает |
|---|---|
transferStatus: "Pending" | Трансфер в процессе — повторить запрос |
transferStatus: "Completed" | Трансфер завершён — токены доставлены |
transferStatus: "Failed" | Трансфер отклонён — обработать ошибку |
incoming.transactionHash != null | Транзакция доставки выполнена |
proofPayload != null | Merkle proof готов (для non-credit трансферов) |
Credit vs Non-credit трансферы
| Тип | Описание | Действия пользователя |
|---|---|---|
| Credit | Релеи автоматически деплоят event и доставляют токены | Только отслеживать статус |
| Non-credit | Пользователь сам деплоит event контракт | Дождаться proofPayload, задеплоить event |
Для non-credit трансферов:
- Дождаться появления
proofPayloadв ответе - Использовать готовую транзакцию из
proofPayload.abiTxдля деплоя Event контракта в сети назначения (см. Отправка трансфера) - После деплоя Event контракта трансфер завершится автоматически
Получение статуса из контракта (on-chain)
Помимо Bridge Aggregator API, статус трансфера можно получить напрямую из Event контракта в блокчейне. Это полезно для:
- Верификации данных API
- Работы без зависимости от централизованного API
- Получения детального on-chain статуса
Адрес Event контракта
proofPayload.abiTx.executionAddress — это адрес EventConfiguration, а не Event контракта. Event контракт деплоится при вызове deployEvent и его адрес вычисляется детерминированно через deriveEventAddress(msgHash) на EventConfiguration. Для получения адреса Event контракта используйте proofPayload.messageHash и вызовите deriveEventAddress на EventConfiguration.
Статусы Event контракта
const EVENT_STATUS = {
0: 'Initializing',
1: 'Pending',
2: 'Confirmed',
3: 'Rejected',
4: 'Cancelled',
5: 'LimitReached',
6: 'LiquidityRequested',
7: 'LiquidityProvided',
8: 'Verified',
} as const;Получение статуса через getDetails
Event контракт имеет метод getDetails(), который возвращает:
| Поле | Тип | Описание |
|---|---|---|
_eventInitData | tuple | Данные инициализации: msgHash (uint256), configuration (address), chainId (int32) |
_initializer | address | Аккаунт, задеплоивший Event контракт |
_meta | cell | Метаданные из EventConfiguration |
_status | uint8 | Числовой статус (см. таблицу выше) |
Для чтения on-chain данных
Чтение состояния контракта требует TVM-провайдера (everscale-inpage-provider). TonConnect поддерживает только отправку транзакций.
import { ProviderRpcClient, Address } from 'everscale-inpage-provider';
const provider = new ProviderRpcClient();
await provider.ensureInitialized();
const eventAbi = {
"ABI version": 2,
functions: [{
name: "getDetails",
inputs: [{ name: "answerId", type: "uint32" }],
outputs: [
{ name: "_eventInitData", type: "tuple", components: [
{ name: "msgHash", type: "uint256" },
{ name: "configuration", type: "address" },
{ name: "chainId", type: "int32" },
]},
{ name: "_initializer", type: "address" },
{ name: "_meta", type: "cell" },
{ name: "_status", type: "uint8" },
],
}],
events: [],
} as const;
const eventAddress = new Address('0:1234...abcd'); // Адрес Event контракта
const eventContract = new provider.Contract(eventAbi, eventAddress);
const { _status, _initializer, _eventInitData } = await eventContract.methods
.getDetails({ answerId: 0 })
.call();
const statusName = EVENT_STATUS[Number(_status) as keyof typeof EVENT_STATUS];
console.log('Event статус:', statusName); // например: "Verified"Получение данных события через getDecodedData
Метод getDecodedData() возвращает декодированные данные события, включая bounty (награду для LP). Используется тот же provider и eventAddress из примера выше.
Разные возвращаемые типы
Структура ответа отличается для Native и Alien Event контрактов. Используйте соответствующий ABI.
const nativeEventAbi = {
"ABI version": 2,
functions: [{
name: "getDecodedData",
inputs: [{ name: "answerId", type: "uint32" }],
outputs: [
{ name: "token_", type: "address" },
{ name: "name_", type: "string" },
{ name: "symbol_", type: "string" },
{ name: "decimals_", type: "uint8" },
{ name: "sender_", type: "address" },
{ name: "amount_", type: "uint128" },
{ name: "recipient_", type: "address" },
{ name: "value_", type: "uint128" },
{ name: "expected_gas_", type: "uint128" },
{ name: "payload_", type: "optional(cell)" },
{ name: "proxy_", type: "address" },
{ name: "tokenWallet_", type: "address" },
{ name: "bounty_", type: "uint128" },
],
}],
events: [],
} as const;
const eventContract = new provider.Contract(nativeEventAbi, eventAddress);
const data = await eventContract.methods.getDecodedData({ answerId: 0 }).call();
console.log('Токен:', data.symbol_);
console.log('Сумма:', data.amount_);
console.log('Получатель:', data.recipient_.toString());
console.log('Bounty:', data.bounty_);const alienEventAbi = {
"ABI version": 2,
functions: [{
name: "getDecodedData",
inputs: [{ name: "answerId", type: "uint32" }],
outputs: [
{ name: "base_chainId_", type: "int32" },
{ name: "base_token_", type: "address" },
{ name: "base_native_proxy_wallet_", type: "address" },
{ name: "name_", type: "string" },
{ name: "symbol_", type: "string" },
{ name: "decimals_", type: "uint8" },
{ name: "amount_", type: "uint128" },
{ name: "recipient_", type: "address" },
{ name: "attached_gas_", type: "uint128" },
{ name: "expected_gas_", type: "uint128" },
{ name: "payload_", type: "optional(cell)" },
{ name: "proxy_", type: "address" },
{ name: "token_", type: "address" },
{ name: "native_proxy_token_wallet", type: "optional(address)" },
],
}],
events: [],
} as const;
const eventContract = new provider.Contract(alienEventAbi, eventAddress);
const data = await eventContract.methods.getDecodedData({ answerId: 0 }).call();
console.log('Токен:', data.symbol_);
console.log('Сумма:', data.amount_);
console.log('Получатель:', data.recipient_.toString());
console.log('Base chain:', data.base_chainId_);Обработка лимитов и Liquidity Requests
Иногда после деплоя Event контракта токены не приходят сразу. Это происходит в двух случаях:
| Ситуация | Event Status | Что произошло | Какие токены |
|---|---|---|---|
| Превышен лимит | LimitReached (5) | Сумма больше дневного лимита безопасности | Native и Alien |
| Не хватает ликвидности | LiquidityRequested (6) | На proxy контракте недостаточно токенов для unlock | Только Native в сети назначения |
В обоих случаях токены не теряются — они заблокированы в Event контракте до разрешения ситуации.
Почему Alien токены не попадают в LiquidityRequested?
Alien токены (не родные для сети назначения) при переводе минтятся (создаются заново), а не берутся из баланса proxy. Поэтому недостаток ликвидности для них невозможен. Native токены (родные для сети назначения) при переводе разблокируются (unlock) из proxy — если на proxy заблокировано недостаточно токенов, возникает LiquidityRequested.
Как определить, что трансфер отложен
Через API: transferStatus остаётся "Pending", а on-chain статус Event контракта — 5 (LimitReached) или 6 (LiquidityRequested).
Через on-chain: вызовите getDetails() на Event контракте:
const { _status } = await eventContract.methods.getDetails({ answerId: 0 }).call();
if (Number(_status) === 5) {
console.log('Превышен дневной лимит — ожидание одобрения');
} else if (Number(_status) === 6) {
console.log('Недостаток ликвидности — можно установить bounty, отменить или повторить');
}Действия пользователя
| Действие | Когда доступно | Кто может вызвать | Описание |
|---|---|---|---|
| Set Bounty | LiquidityRequested (6) | sender / recipient | Назначить награду провайдеру ликвидности |
| Cancel | LiquidityRequested (6) | sender / recipient | Отменить трансфер и вернуть токены |
| Cancel | LimitReached (5) | только limitApprover | Отклонить трансфер (администратор) |
| Retry | LimitReached (5) / LiquidityRequested (6) | sender / recipient / initializer | Повторить после одобрения лимита или появления ликвидности |
Set Bounty — установка награды
Устанавливает награду для провайдера ликвидности. Доступно только в статусе LiquidityRequested (6). Может вызвать sender или recipient.
import { ProviderRpcClient, Address } from 'everscale-inpage-provider';
const provider = new ProviderRpcClient();
await provider.ensureInitialized();
const eventAbi = {
"ABI version": 2,
functions: [{
name: "setBounty",
inputs: [{ name: "_bounty", type: "uint128" }],
outputs: [],
}],
events: [],
} as const;
const eventAddress = new Address('0:1234...abcd'); // Адрес Event контракта
const eventContract = new provider.Contract(eventAbi, eventAddress);
const senderAddress = new Address('0:3333...cccc'); // sender или recipient
await eventContract.methods
.setBounty({ _bounty: '1000000000' }) // 1 токен в nano-единицах
.send({
from: senderAddress,
amount: '500000000', // 0.5 для газа
bounce: true,
});
console.log('Bounty установлен');Cancel — отмена трансфера
Отменяет трансфер и возвращает токены на указанный адрес. Доступно в статусе LiquidityRequested (6) для sender/recipient, и в LimitReached (5) для limitApprover.
Разные параметры для Native и Alien
Alien Event контракт требует дополнительный параметр _predeployedTokenData. Для Native он не нужен.
import { ProviderRpcClient, Address } from 'everscale-inpage-provider';
const provider = new ProviderRpcClient();
await provider.ensureInitialized();
const nativeEventAbi = {
"ABI version": 2,
functions: [{
name: "cancel",
inputs: [
{ name: "_newRecipient", type: "address" },
{ name: "_remainingGasTo", type: "address" },
{ name: "_expectedGas", type: "uint128" },
{ name: "_eventPayload", type: "optional(cell)" },
{ name: "_expectedGasReceiver", type: "address" },
],
outputs: [],
}],
events: [],
} as const;
const eventAddress = new Address('0:1234...abcd');
const eventContract = new provider.Contract(nativeEventAbi, eventAddress);
const senderAddress = new Address('0:3333...cccc');
await eventContract.methods
.cancel({
_newRecipient: senderAddress, // Куда вернуть токены
_remainingGasTo: senderAddress, // Куда вернуть остаток газа
_expectedGas: '0',
_eventPayload: null, // Без дополнительного payload
_expectedGasReceiver: senderAddress,
})
.send({
from: senderAddress,
amount: '1000000000', // 1.0 для газа
bounce: true,
});
console.log('Трансфер отменён');import { ProviderRpcClient, Address } from 'everscale-inpage-provider';
const provider = new ProviderRpcClient();
await provider.ensureInitialized();
const alienEventAbi = {
"ABI version": 2,
functions: [{
name: "cancel",
inputs: [
{ name: "_newRecipient", type: "address" },
{ name: "_remainingGasTo", type: "address" },
{ name: "_expectedGas", type: "uint128" },
{ name: "_eventPayload", type: "optional(cell)" },
{ name: "_predeployedTokenData", type: "optional(cell)" },
{ name: "_expectedGasReceiver", type: "address" },
],
outputs: [],
}],
events: [],
} as const;
const eventAddress = new Address('0:1234...abcd');
const eventContract = new provider.Contract(alienEventAbi, eventAddress);
const senderAddress = new Address('0:3333...cccc');
await eventContract.methods
.cancel({
_newRecipient: senderAddress,
_remainingGasTo: senderAddress,
_expectedGas: '0',
_eventPayload: null,
_predeployedTokenData: null,
_expectedGasReceiver: senderAddress,
})
.send({
from: senderAddress,
amount: '1000000000',
bounce: true,
});
console.log('Трансфер отменён');Retry — повторная попытка
Повторяет попытку доставки токенов. Используйте после:
- Одобрения лимита администратором (из статуса
LimitReached) - Появления ликвидности на proxy (из статуса
LiquidityRequested)
import { ProviderRpcClient, Address } from 'everscale-inpage-provider';
const provider = new ProviderRpcClient();
await provider.ensureInitialized();
const eventAbi = {
"ABI version": 2,
functions: [{
name: "retry",
inputs: [],
outputs: [],
}],
events: [],
} as const;
const eventAddress = new Address('0:1234...abcd');
const eventContract = new provider.Contract(eventAbi, eventAddress);
const senderAddress = new Address('0:3333...cccc');
await eventContract.methods
.retry({})
.send({
from: senderAddress,
amount: '500000000', // 0.5 для газа
bounce: true,
});
console.log('Retry отправлен — трансфер перейдёт в статус Verified');