Skip to content

Отслеживание трансфера

Предварительные шаги

Перед отслеживанием трансфера необходимо его отправить. См. Отправка трансфера для получения 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Описание
TvmTvmNativeNativeТрансфер native токена (lock → mint)
TvmTvmAlienAlienТрансфер alien токена (burn → unlock)

Статусы трансфера

Два уровня статусов

В системе существует два уровня статусов:

УровеньГде хранитсяНазначение
TransferStatusBridge Aggregator APIАгрегированный статус для UI/интеграций
Event Contract StatusOn-chain (Event контракт)Детальное состояние верификации события

Связь: Bridge Aggregator API агрегирует on-chain статусы Event контракта в упрощённый TransferStatus:

Event Contract Status                    →    TransferStatus (API)
─────────────────────────────────────────────────────────────────────
Initializing, Pending, Verified          →    Pending
Confirmed, LiquidityProvided             →    Completed
Rejected, Cancelled                      →    Failed

TransferStatus (API level)

Используется в ответах Bridge Aggregator API (/v2/transfers/status, /v2/transfers/search).

СтатусКодОписание
Pending1Событие создано, ожидает подтверждения в сети назначения
Completed2Трансфер полностью завершён (токены доставлены)
Failed3Трансфер отклонён релеями

Event Contract Status (on-chain level)

Детальные статусы Event контракта в блокчейне. Используются для понимания на каком этапе верификации находится событие.

СтатусКодОписание→ TransferStatus
Initializing0Event контракт задеплоенPending
Pending1Ожидание верификацииPending
Confirmed2Подтверждён, proxy вызван, токены доставленыCompleted
Rejected3ОтклонёнFailed
Cancelled4Отменён пользователемFailed
LimitReached5Превышен дневной лимит, требуется ликвидностьPending
LiquidityRequested6Запрос ликвидности созданPending
LiquidityProvided7Ликвидность предоставлена, токены доставленыCompleted
Verified8Merkle proof проверен, ожидание деплоя токеновPending

Переход для trustless: PendingVerifiedConfirmed

Диаграмма переходов статусов

Получение статуса по 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

Параметры запроса

ПараметрТипОбязательныйОписание
outgoingTransactionHashstringTransfer ID (hex, 64 символа)
dappChainIdnumberChain ID сети отправления (TON = -239, Tycho = 2000)
timestampCreatedFromnumberUnix timestamp для фильтрации (опционально)

Пример запроса (TvmTvm)

bash
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
    }
  }'

Пример ответа

json
{
  "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 — данные трансфера

ПолеТипОписание
transferStatusstringСтатус: "Pending", "Completed", "Failed"
timestampCreatedAtnumberUnix timestamp создания трансфера

outgoing — данные исходящей стороны

Все поля non-nullable. При отсутствии данных подставляются дефолты ("" для строк, "0" для чисел).

ПолеТипОписание
tokenTypestring"Native" или "Alien"
chainIdnumberChain ID сети
userAddressstringАдрес отправителя
tokenAddressstringАдрес токена в сети отправления
proxyAddressstringАдрес proxy контракта
volumeExecstringСумма в human-readable формате
volumeUsdtExecstringСумма в USDT эквиваленте
feeVolumeExecstringУдержанная комиссия
messageHashstringHash сообщения события
transactionHashstringHash транзакции (= Transfer ID)

incoming — данные входящей стороны

Большинство полей non-nullable (дефолты "" / "0" пока трансфер не завершён). Только feeVolumeExec и transactionHash nullable.

ПолеТипОписание
tokenTypestring"Native" или "Alien"
chainIdnumberChain ID сети
userAddressstringАдрес получателя
tokenAddressstringАдрес токена в сети назначения (пустая строка, пока трансфер не завершён)
proxyAddressstringАдрес proxy контракта (пустая строка, пока трансфер не завершён)
volumeExecstringСумма в human-readable формате ("0" пока не завершён)
volumeUsdtExecstringСумма в USDT эквиваленте ("0" пока не завершён)
feeVolumeExecstring | nullУдержанная комиссия
messageHashstringHash сообщения события (пустая строка, пока не завершён)
transactionHashstring | nullHash транзакции доставки (null пока не завершён)

proofPayload — данные для non-credit трансферов

ПолеТипОписание
txBlockProofstringProof блока (BOC base64)
txProofstringMerkle proof транзакции (BOC base64)
messageHashstringHash сообщения события
outMessageIndexnumberИндекс исходящего сообщения в транзакции
eventobjectДанные события (см. ниже)
abiTxobject | nullГотовая транзакция для deployEvent (см. ниже)

proofPayload.abiTx — готовая транзакция для non-credit

ПолеТипОписание
txstringPayload транзакции (BOC base64)
executionAddressstringАдрес EventConfiguration контракта
attachedValuestringТребуемый газ в nano-единицах
abiMethodstringМетод контракта (deployEvent)
abistringABI контракта
paramsstringПараметры вызова (JSON string)

proofPayload.event — данные события

ПолеТипОписание
tokenTypestring"Native" или "Alien"
chainIdnumberChain ID сети назначения
tokenstringАдрес токена
amountstringСумма в nano-единицах
recipientstringАдрес получателя
valuestringПрикреплённое значение (газ)
expectedGasstringОжидаемый газ
remainingGasTostringАдрес для возврата газа
senderstringАдрес отправителя
payloadstringДополнительный payload (BOC base64)
nativeProxyWalletstring | nullАдрес wallet прокси (для Native)
namestring | nullНазвание токена
symbolstring | nullСимвол токена
decimalsnumber | 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 != nullProof готовМожно деплоить event (non-credit)
incoming.transactionHash != nullВторая часть выполненаТрансфер почти завершён

История трансферов

API Endpoint

POST https://tetra-history-api.chainconnect.com/v2/transfers/search
Content-Type: application/json

Параметры запроса

ПараметрТипОбязательныйОписание
userAddressesstring[]Фильтр по адресам пользователя (макс 7)
transferKindsstring[]Тип трансфера: ["TvmToTvm"]
statusesstring[]Фильтр по статусам: ["Pending", "Completed", "Failed"]
fromTvmChainIdnumberChain ID сети отправления
toTvmChainIdnumberChain ID сети назначения
createdAtGenumberUnix timestamp >= (от какой даты)
createdAtLenumberUnix timestamp <= (до какой даты)
orderingstringСортировка: "CreatedAtAscending" или "CreatedAtDescending"
limitnumberЛимит записей (макс количество в ответе)
offsetnumberСмещение (для пагинации)
isNeedTotalCountbooleanВозвращать ли общее количество трансферов

Пример запроса

bash
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
  }'

Пример ответа

json
{
  "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 != nullMerkle proof готов (для non-credit трансферов)

Credit vs Non-credit трансферы

ТипОписаниеДействия пользователя
CreditРелеи автоматически деплоят event и доставляют токеныТолько отслеживать статус
Non-creditПользователь сам деплоит event контрактДождаться proofPayload, задеплоить event

Для non-credit трансферов:

  1. Дождаться появления proofPayload в ответе
  2. Использовать готовую транзакцию из proofPayload.abiTx для деплоя Event контракта в сети назначения (см. Отправка трансфера)
  3. После деплоя 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 контракта

typescript
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(), который возвращает:

ПолеТипОписание
_eventInitDatatupleДанные инициализации: msgHash (uint256), configuration (address), chainId (int32)
_initializeraddressАккаунт, задеплоивший Event контракт
_metacellМетаданные из EventConfiguration
_statusuint8Числовой статус (см. таблицу выше)

Для чтения on-chain данных

Чтение состояния контракта требует TVM-провайдера (everscale-inpage-provider). TonConnect поддерживает только отправку транзакций.

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

typescript
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_);
typescript
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 контракте:

typescript
const { _status } = await eventContract.methods.getDetails({ answerId: 0 }).call();

if (Number(_status) === 5) {
  console.log('Превышен дневной лимит — ожидание одобрения');
} else if (Number(_status) === 6) {
  console.log('Недостаток ликвидности — можно установить bounty, отменить или повторить');
}

Действия пользователя

ДействиеКогда доступноКто может вызватьОписание
Set BountyLiquidityRequested (6)sender / recipientНазначить награду провайдеру ликвидности
CancelLiquidityRequested (6)sender / recipientОтменить трансфер и вернуть токены
CancelLimitReached (5)только limitApproverОтклонить трансфер (администратор)
RetryLimitReached (5) / LiquidityRequested (6)sender / recipient / initializerПовторить после одобрения лимита или появления ликвидности

Set Bounty — установка награды

Устанавливает награду для провайдера ликвидности. Доступно только в статусе LiquidityRequested (6). Может вызвать sender или recipient.

typescript
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 он не нужен.

typescript
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('Трансфер отменён');
typescript
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)
typescript
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');

ChainConnect Bridge Documentation