EnraloEnralo

API для разработчиков

Покрывайте комиссию сети за переводы USDT ваших пользователей прямо из своего продукта: посчитайте перевод, получите котировку, исполните заказ, заберите результат вебхуком.

Что даёт API

Котировки с фиксированной ценой

Котировка фиксирует цену и объём ресурса на час, поэтому стоимость заказа не меняется между расчётом и оплатой.

Идемпотентные заказы

Каждый заказ принимает Idempotency-Key: повторный запрос после таймаута вернёт тот же заказ, а не создаст дубль.

Подписанные вебхуки

Каждое событие подписано HMAC-SHA256, содержит идентификатор для дедупликации и повторяется с задержками, пока вы не ответите 2xx.

Предоплаченный баланс

Заказы списываются с баланса в TRX, который пополняется TRX, USDT (TRC-20) или TON. На низком остатке приходит событие balance.low.

Расчёт перевода до котировки

POST /v1/transfer-estimate отвечает на вопрос, от которого зависит всё остальное: сколько ресурса нужно этому конкретному переводу. Передайте кошелёк, с которого уйдёт USDT, и получателя, если он известен. Мы симулируем перевод в сети, а если на кошельке отправителя USDT пока нет — считаем по состоянию кошелька получателя. В котировку from_address идёт как target_address: ресурс делегируется отправителю.

amount
Сколько докупить — значение готово для поля amount в котировке. Ноль, если отправителю уже хватает. Не бывает меньше минимального заказа, поэтому небольшая доплата тоже пройдёт.
purchase_needed
False — заказ можно не создавать: отправитель покрывает этот перевод сам.
required_energy
Сколько нужно на перевод целиком, до вычета того, что у отправителя уже есть.
available_energy
Сколько уже есть на кошельке отправителя. Null — узел не ответил, тогда считаем как ноль и берём полный объём.
recipient_holds_usdt
Был ли на кошельке получателя USDT. Первый перевод на пустой кошелёк стоит сети примерно вдвое дороже.
basis
Откуда взята цифра: onchain — симуляция вашего перевода, recipient — состояние кошелька получателя, worst_case — опираться было не на что, взяли дорогой тариф.

Ответ кэшируется на 20 секунд для пары кошельков, лимит — 60 запросов в минуту на клиента. Без to_address мы не отличим первый перевод от обычного и вернём более дорогой вариант, поэтому передавайте его, когда он есть.

Схема интеграции

Четыре вызова: посчитать, сколько нужно переводу, запросить котировку, исполнить её заказом и получить статус вебхуком или опросом заказа.

cURL
# 1. How much to buy for this transfer
curl -X POST https://api.enralo.com/v1/transfer-estimate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from_address":"SENDER","to_address":"RECIPIENT"}'
# -> {"amount":65000,"required_energy":65000,"available_energy":0,
#     "purchase_needed":true,"basis":"onchain","resource_type":"energy","duration":"1h"}

# 2. Quote (amount and target_address come from the estimate)
curl -X POST https://api.enralo.com/v1/quotes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"resource_type":"energy","amount":65000,"duration":"1h","target_address":"SENDER"}'

# 3. Execute quote (idempotent)
curl -X POST https://api.enralo.com/v1/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-unique-key-1" \
  -d '{"quote_id":"QUOTE_ID"}'

# 4. Status
curl https://api.enralo.com/v1/orders/ORDER_ID -H "Authorization: Bearer YOUR_API_KEY"
Node.js
const API = 'https://api.enralo.com';
const KEY = process.env.TRXPORTAL_API_KEY;

const call = (path, body, extraHeaders = {}) =>
  fetch(`${API}${path}`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json', ...extraHeaders },
    body: JSON.stringify(body),
  }).then(r => r.json());

// sender pays the USDT, recipient receives it
async function coverTransferFee(sender, recipient) {
  const estimate = await call('/v1/transfer-estimate', {
    from_address: sender,
    to_address: recipient,
  });

  // The sender already has enough resource — nothing to buy
  if (!estimate.purchase_needed) return null;

  const quote = await call('/v1/quotes', {
    resource_type: estimate.resource_type,
    amount: estimate.amount,
    duration: estimate.duration,
    target_address: sender,
  });

  return call('/v1/orders', { quote_id: quote.quote_id }, {
    'Idempotency-Key': `cover-${sender}-${Date.now()}`,
  }); // statuses via webhook, or poll GET /v1/orders/{id}
}
Вебхук
// Verify incoming webhook signature (Node.js / Express)
const crypto = require('crypto');

app.post('/webhooks/trxportal', express.raw({ type: '*/*' }), (req, res) => {
  const expected = crypto
    .createHmac('sha256', process.env.TRXPORTAL_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');
  if (req.headers['x-tp-signature'] !== expected) return res.status(401).end();

  // Delivery headers: X-Tp-Event-Id (dedupe), X-Tp-Timestamp
  const event = JSON.parse(req.body);
  // event.event_type: order.submitted | order.delegated | order.completed |
  //                   order.failed | order.refunded | deposit.credited |
  //                   balance.low | webhook.test
  res.status(200).end();
});

Статусы заказа

created
Заказ принят и поставлен в очередь на обработку.
funds_reserved
Сумма удерживается на балансе до доставки заказа или возврата.
submitted
Заказ отправлен поставщику ресурса и ждёт делегирования.
delegated
Транзакция делегирования подтверждена в сети TRON, доступен хеш транзакции.
completed
Срок аренды истёк, заказ закрыт.
failed
Ресурс доставить не удалось, удержание снято.
refunded
Оплата возвращена на баланс.

Начните интеграцию

Создайте API-ключ в кабинете и запустите первую котировку за пару минут. Полный справочник — в документации OpenAPI.

API для разработчиков — Enralo