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 мы не отличим первый перевод от обычного и вернём более дорогой вариант, поэтому передавайте его, когда он есть.
Схема интеграции
Четыре вызова: посчитать, сколько нужно переводу, запросить котировку, исполнить её заказом и получить статус вебхуком или опросом заказа.
# 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"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.