GuidesОтправить перевод

Отправить перевод

Создать исходящий перевод с идемпотентностью, разобраться в состояниях (резерв, awaiting_approval, confirmed) и отменить зависшую заявку.

Перевод не уходит в сеть сразу: сумма сначала резервируется, затем Policy Engine решает allow / queue / block, и только потом MPC-ноды подписывают транзакцию. Здесь — как отправить перевод, что происходит с его состоянием и как отменить зависшую заявку. Механику резерва см. в Журнале, решения — в Policy Engine.

Шаг 1. Отправьте перевод

POST /api/v1/vaults/{code}/transfers создаёт исходящий перевод. Всегда передавайте idempotencyKey: повтор с тем же ключом вернёт уже созданный перевод, а не задвоит платёж.

curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/transfers" \
  -H "Authorization: Bearer $V3_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fromAddressId": "cmr3f41z20001psp7phmyapw3",
    "toAddress": "TQ2m...p4rX",
    "token": "usdt",
    "amount": "1350.00",
    "idempotencyKey": "payout-2026-03-14-001"
  }'

Под капотом платформа резолвит адрес и токен, конвертирует сумму по decimals, проверяет баланс и прогоняет запрос через Policy Engine (action=transfer). При запрете вернётся 403, при нехватке средств — ошибка INSUFFICIENT_BALANCE.

{
  "transaction": { "...": "..." },
  "fromAddressId": "cmr3f41z20001psp7phmyapw3",
  "toAddress": "TQ2m...p4rX",
  "amount": "1350000000",
  "amountDecimal": "1350.00"
}

Сумма возвращается в двух видах: amount — в минимальных единицах (raw), amountDecimal — в человеческом формате.

Набор полей тела приведён для примера. Точную схему запроса сверьте со Справочником API на странице создания перевода.

Шаг 2. Три состояния перевода

Исход зависит от Policy Engine:

  • allow — перевод исполняется сразу (в демо-режиме успешный broadcast сразу считается confirmed).
  • queue — перевод создаётся в статусе awaiting_approval; сумма держится в reserved и ждёт m-of-n подтверждений.
  • block — перевод не создаётся, приходит 403 с причиной.

При отклонении или отмене зарезервированная сумма возвращается в available.

Шаг 3. Проверьте статус

curl "[BASE_URL]/api/v1/vaults/acme-otc/transfers/TRANSFER_ID" \
  -H "Authorization: Bearer $V3_TOKEN"

GET /api/v1/vaults/{code}/transfers/{id} возвращает статус, суммы (raw и decimal) и — для переводов, требующих одобрения, — снапшот одобряющих с их голосами.

Шаг 4. Подтвердите (если перевод в очереди)

Если перевод в статусе awaiting_approval, члены approver-группы голосуют:

curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/transfers/TRANSFER_ID/approvals" \
  -H "Authorization: Bearer $V3_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "approve" }'
  • approve добирает порог — перевод исполняется.
  • reject — вето: перевод сразу rejected, средства возвращаются.
  • Инициатор не голосует за свой перевод; у каждого — один голос.

Подробнее о заявках — на странице Аппрувалы.

Точное имя поля голоса (здесь — decision) сверьте со Справочником API на странице голосования по переводу.

Шаг 5. Отмените зависший перевод

Если одобряющие бездействуют, инициатор может отозвать перевод, пока тот ждёт одобрения:

curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/transfers/TRANSFER_ID/cancel" \
  -H "Authorization: Bearer $V3_TOKEN"

cancel переводит заявку в rejected и возвращает зарезервированные средства. После одобрения или исполнения отменить нельзя.

Что дальше