Back to Blog

Developer / C02

Купить TRON Energy в 5 строк кода: MERX JavaScript SDK

MERX JavaScript SDK позволяет программно покупать TRON energy всего в пяти строк кода — установите пакет, инициализируйте клиент, проверьте цены, создайте заказ и подтвердите делегирование. Эта статья охватывает полный SDK от установки до развёртывания в production, включая TypeScript типы, обработку ошибок и все методы, доступные в четырёх модулях: prices, orders, balance и webhooks.

Проблема прямого использования API поставщиков

У каждого поставщика TRON energy есть собственный API. Интеграция с одним поставщиком проста. Интеграция со всеми семью или восемью поставщиками, чтобы гарантировать лучшую цену — это серьёзный инженерный проект. Нужно обрабатывать различные схемы аутентификации, форматы ответов, коды ошибок, ограничения по частоте запросов и логику отказоустойчивости.

SDK MERX абстрагирует всё это в единого клиента с единообразным интерфейсом. За кулисами платформа MERX опрашивает всех поставщиков каждые 30 секунд, поддерживает индекс цен в реальном времени и маршрутизирует ваши заказы к самому дешёвому доступному источнику с автоматической отказоустойчивостью.

Установка

SDK требует Node.js 18 или новее. Использует встроенный fetch без зависимостей во время выполнения.

npm install merx-sdk
yarn add merx-sdk
pnpm add merx-sdk

Пакет поставляется как ESM с полными TypeScript объявлениями типов и исходными картами.

Пять строк для покупки energy

Вот полный процесс в минимальной форме:

import { MerxClient } from 'merx-sdk'

const merx = new MerxClient({ apiKey: process.env.MERX_API_KEY })
const prices = await merx.prices.list()
const order = await merx.orders.create({
  resource_type: 'ENERGY',
  amount: 65000,
  target_address: 'TYourTargetAddressHere',
  duration_sec: 3600,
})
console.log(`Order ${order.id}: ${order.status}`)

Строка за строкой:

  1. Импортируем класс клиента.
  2. Инициализируем с вашим API ключом. Ключ начинается с sk_live_ и создаётся в панели управления MERX на сайте merx.exchange.
  3. Получаем текущие цены от всех подключённых поставщиков. Это опционально, но полезно для отображения состояния рынка перед заказом.
  4. Создаём рыночный заказ на 65 000 единиц energy, делегированных на ваш адрес на один час. Платформа автоматически выбирает самого дешёвого поставщика.
  5. Логируем ID заказа и статус. Заказ начинается в статусе PENDING и переходит в FILLED после подтверждения делегирования в блокчейне.

Это вся интеграция. Никакого выбора поставщика, никакой логики отказоустойчивости, никакого кода сравнения цен.

Конфигурация клиента

import { MerxClient } from 'merx-sdk'

const merx = new MerxClient({
  apiKey: 'sk_live_your_key_here',   // Обязательно
  baseUrl: 'https://merx.exchange',  // Опционально, по умолчанию production
})

apiKey — это единственный обязательный параметр. baseUrl может быть переопределён для тестирования в staging окружении.

Модуль Prices

Модуль merx.prices предоставляет пять методов для запроса данных рынка в реальном времени.

prices.list()

Возвращает текущие цены от всех активных поставщиков.

const prices = await merx.prices.list()

for (const p of prices) {
  const cheapest = p.energy_prices[0]
  if (cheapest) {
    console.log(`${p.provider}: ${cheapest.price_sun} SUN/energy, ${p.available_energy} available`)
  }
}

Каждый объект ProviderPrice включает:

prices.best(resource, amount?)

Возвращает единственную самую дешёвую точку цены для заданного типа ресурса.

const best = await merx.prices.best('ENERGY')
console.log(`Cheapest: ${best.price_sun} SUN from ${best.provider}`)

// С фильтром минимального количества
const bestLarge = await merx.prices.best('ENERGY', 500000)

Опциональный параметр amount фильтрует поставщиков, у которых недостаточно мощности для выполнения вашего заказа.

prices.history(params?)

Возвращает исторические данные цен для анализа и визуализации.

const history = await merx.prices.history({
  provider: 'sohu',
  resource: 'ENERGY',
  period: '24h',
})

for (const entry of history) {
  console.log(`${entry.polled_at}: ${entry.price_sun} SUN, ${entry.available} available`)
}

Доступные периоды: '1h', '6h', '24h', '7d', '30d'. Все параметры фильтрации опциональны.

prices.stats()

Возвращает статистику по всему рынку.

const stats = await merx.prices.stats()
console.log(`Best price: ${stats.best_price_sun} SUN`)
console.log(`Average: ${stats.avg_price_sun} SUN`)
console.log(`Providers online: ${stats.total_providers}`)
console.log(`Cheapest-provider changes (24h): ${stats.cheapest_changes_24h}`)

prices.preview(params)

Предварительно показывает стоимость заказа перед его размещением. Возвращает лучший подходящий поставщик и альтернативные варианты.

const preview = await merx.prices.preview({
  resource: 'ENERGY',
  amount: 100000,
  duration: 86400,
  max_price_sun: 35,
})

if (preview.best) {
  console.log(`Best: ${preview.best.provider} at ${preview.best.cost_trx} TRX`)
  console.log(`Price: ${preview.best.price_sun} SUN/unit`)
}

for (const fb of preview.fallbacks) {
  console.log(`Fallback: ${fb.provider} at ${fb.cost_trx} TRX`)
}

if (preview.no_providers) {
  console.log('No providers available for this configuration')
}

Параметр max_price_sun фильтрует поставщиков, чьи цены превышают вашу максимальную цену.

Модуль Orders

orders.create(params)

Создаёт заказ на energy или bandwidth.

const order = await merx.orders.create({
  resource_type: 'ENERGY',
  amount: 65000,
  target_address: 'TYourTargetAddress',
  duration_sec: 3600,
  order_type: 'MARKET',          // Опционально, по умолчанию 'MARKET'
  max_price_sun: 30,             // Опционально, требуется для LIMIT заказов
  idempotency_key: 'unique-id',  // Опционально, предотвращает дублирование
})

console.log(`Order ${order.id} created`)
console.log(`Status: ${order.status}`)

Типы заказов:

idempotency_key критичен для production систем. Если происходит ошибка сети и вы повторяете запрос с тем же ключом, API возвращает исходный заказ вместо создания дубликата.

orders.list(limit?, offset?, status?)

Список заказов с постраничной навигацией.

const { orders, total } = await merx.orders.list(10, 0, 'FILLED')
console.log(`${total} filled orders total`)

for (const o of orders) {
  console.log(`${o.id}: ${o.amount} ${o.resource_type}, cost: ${o.total_cost_sun} SUN`)
}

orders.get(id)

Возвращает один заказ с деталями исполнения.

const order = await merx.orders.get('ord_abc123')

console.log(`Status: ${order.status}`)
console.log(`Fills: ${order.fills.length}`)

for (const fill of order.fills) {
  console.log(`  ${fill.provider}: ${fill.amount} units at ${fill.price_sun} SUN`)
  console.log(`  Verified: ${fill.verified}`)
  if (fill.tronscan_url) {
    console.log(`  TX: ${fill.tronscan_url}`)
  }
}

Массив fills показывает точно, как был выполнен заказ. Каждое исполнение включает имя поставщика, выделённое количество, цену за единицу, стоимость, ID транзакции в блокчейне и то, было ли делегирование подтверждено в цепи.

Модуль Balance

balance.get()

Возвращает текущие балансы аккаунта.

const balance = await merx.balance.get()
console.log(`TRX: ${balance.trx}`)
console.log(`USDT: ${balance.usdt}`)
console.log(`Locked: ${balance.trx_locked}`)

Поле trx_locked показывает TRX, зарезервированные для ожидающих заказов.

balance.depositInfo()

Возвращает адрес депозита и памятку для пополнения вашего аккаунта MERX.

const info = await merx.balance.depositInfo()
console.log(`Send TRX to: ${info.address}`)
console.log(`Include memo: ${info.memo}`)
console.log(`Minimum deposit: ${info.min_amount_trx} TRX`)

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

balance.withdraw(params)

Выводит TRX или USDT на внешний TRON адрес.

const withdrawal = await merx.balance.withdraw({
  address: 'TYourExternalAddress',
  amount: 100,
  currency: 'TRX',
  idempotency_key: 'withdraw-unique-id',
})

console.log(`Withdrawal ${withdrawal.id}: ${withdrawal.status}`)

balance.history(period?) и balance.summary()

const history = await merx.balance.history('7D')
console.log(`${history.length} transactions in last 7 days`)

const summary = await merx.balance.summary()
console.log(`Total orders: ${summary.total_orders}`)
console.log(`Total energy: ${summary.total_energy}`)
console.log(`Average price: ${summary.avg_price_sun} SUN`)

Модуль Webhooks

webhooks.create(params)

Создаёт подписку на webhook. secret возвращается только при создании.

const webhook = await merx.webhooks.create({
  url: 'https://your-server.com/merx-webhook',
  events: ['order.filled', 'order.failed', 'deposit.received'],
})

console.log(`Webhook ID: ${webhook.id}`)
console.log(`Secret: ${webhook.secret}`)

webhooks.list() и webhooks.delete(id)

const webhooks = await merx.webhooks.list()
console.log(`${webhooks.filter(w => w.is_active).length} active webhooks`)

await merx.webhooks.delete('wh_abc123')

Обработка ошибок

Все ошибки API выбрасываются как экземпляры MerxError с машиночитаемым code и человекочитаемым message.

import { MerxClient, MerxError } from 'merx-sdk'

const merx = new MerxClient({ apiKey: process.env.MERX_API_KEY })

try {
  await merx.orders.create({
    resource_type: 'ENERGY',
    amount: 65000,
    target_address: 'TInvalidAddress',
    duration_sec: 3600,
  })
} catch (err) {
  if (err instanceof MerxError) {
    console.error(`[${err.code}]: ${err.message}`)
    // Output: [INVALID_ADDRESS]: Target address is not a valid TRON address
  }
}

Частые коды ошибок:

Data table
КодЗначение
UNAUTHORIZEDНеверный или отсутствующий API ключ
INSUFFICIENT_FUNDSБаланс аккаунта слишком низкий
INVALID_ADDRESSАдрес цели не является корректным TRON адресом
ORDER_NOT_FOUNDID заказа не существует
INVALID_AMOUNTКоличество ниже минимума или превышает лимиты
DUPLICATE_REQUESTКлюч идемпотентности уже использован
RATE_LIMITEDСлишком много запросов
PROVIDER_UNAVAILABLEНет доступных поставщиков

TypeScript типы

Все типы экспортируются из пакета и могут быть использованы для аннотаций типов во всём вашем приложении:

import type {
  ProviderPrice,
  PricePoint,
  PriceHistoryEntry,
  PriceStats,
  OrderPreview,
  PreviewMatch,
  Order,
  OrderWithFills,
  Fill,
  CreateOrderParams,
  OrderType,
  OrderStatus,
  ResourceType,
  Balance,
  DepositInfo,
  Withdrawal,
  Webhook,
} from 'merx-sdk'

SDK совместим со strict режимом и не создаёт типы any. Каждый ответ полностью типизирован.

Production пример: автоматизированный процесс передачи USDT

Вот полный production паттерн, который проверяет цены, создаёт заказ и опрашивает статус завершения:

import { MerxClient, MerxError } from 'merx-sdk'
import { randomUUID } from 'node:crypto'

const merx = new MerxClient({ apiKey: process.env.MERX_API_KEY! })

async function ensureEnergyAndTransfer(targetAddress: string) {
  // Предварительно проверяем стоимость
  const preview = await merx.prices.preview({
    resource: 'ENERGY',
    amount: 65000,
    duration: 3600,
  })

  if (preview.no_providers) {
    throw new Error('No energy providers available')
  }

  console.log(`Best price: ${preview.best!.cost_trx} TRX from ${preview.best!.provider}`)

  // Создаём заказ с идемпотентностью
  const order = await merx.orders.create({
    resource_type: 'ENERGY',
    amount: 65000,
    target_address: targetAddress,
    duration_sec: 3600,
    idempotency_key: randomUUID(),
  })

  // Опрашиваем пока не будет выполнено (в production используйте webhooks)
  let status = order.status
  while (status === 'PENDING' || status === 'EXECUTING') {
    await new Promise(r => setTimeout(r, 2000))
    const updated = await merx.orders.get(order.id)
    status = updated.status

    if (status === 'FILLED') {
      console.log(`Energy delegated. Fills:`)
      for (const fill of updated.fills) {
        console.log(`  ${fill.provider}: ${fill.amount} units, TX: ${fill.tronscan_url}`)
      }
    }
  }

  if (status === 'FAILED') {
    throw new Error(`Order ${order.id} failed`)
  }

  // Energy теперь доступен на адресе цели
  // Продолжаем с передачей USDT
}

В production замените цикл опроса на слушатель webhook. Создайте подписку на webhook для события order.filled, и ваш сервер будет уведомлён в момент подтверждения делегирования в блокчейне.

Требования и совместимость

Ресурсы

SDK открытого исходного кода и доступен на GitHub. Приветствуются contributions и отчёты об ошибках.

Попробуйте прямо сейчас с AI

Добавьте MERX в Claude Desktop или любой MCP-совместимый клиент — никаких установок, API ключ не требуется для инструментов только для чтения:

{
  "mcpServers": {
    "merx": {
      "url": "https://merx.exchange/mcp/sse"
    }
  }
}

Спросите у AI агента: "Какая сейчас самая дешёвая TRON energy?" и получите живые цены от всех подключённых поставщиков.

Полная документация MCP: merx.exchange/docs/tools/mcp-server


All Articles