API, SDK и виджеты

API обмена криптовалют, SDK и виджет

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

  • Вызовов на интеграцию6
  • Первое предложение200–400 мс через SSE
  • Провайдерывсе включённые, один запрос
  • Брендингваш — интерфейс SwapZilla не нужен

Собрано на/v1/partner/quotes-sse/v1/assets/v1/providers/v1/validate-address/v1/partner/orders

Шесть вызовов — это работающий обменник. Список активов, стрим предложений всех подключённых провайдеров, проверка адреса, создание ордера, опрос статуса, результат — всё под вашим брендом и без кастодиального хранения: монеты пользователя уходят провайдеру, а не SwapZilla и не вам.

  • Один запрос котировки веером уходит во все включённые обменники сразу.
  • Server-sent events отдают первое предложение за 200–400 мс.
  • Приватные обмены через Monero — это два дополнительных эндпоинта, а не другая интеграция.
  • Устанавливать нечего: поверхность API настолько мала, что клиент пишется свой.

Шесть вызовов

ВызовЗачем нуженКлюч
GET /v1/assetsВыбор валют: активы и сети, за которыми стоит провайдер.нет
GET /v1/providersНазвания обменников и их включённость — для строки «работает на».нет
GET /v1/validate-addressПроверка формата адреса до отправки формы. known:false — «не проверено», а не «верно».нет
GET /v1/partner/quotes-sseЖивые предложения по мере ответа каждого провайдера.да
POST /v1/partner/ordersПревращает выбранное предложение в адрес для депозита.да
GET /v1/partner/orders/{id}Статус до зачисления: в DONE лежат AmountToReceived и TxID.да

Ещё два — когда понадобятся: /v1/partner/private-quotes и /v1/partner/private-orders проводят обмен через промежуточный анонимный актив двумя связанными плечами, а /v1/export/rates.xml публикует лучший кросс-провайдерский курс по каждому направлению в формате мониторингов.

Клиент примерно на тридцать строк

SDK-пакета для установки нет — и поверхности API он не нужен. Вот всё целиком:

const BASE = "https://api.swapzilla.io";

export class SwapZilla {
  constructor(private key: string) {}

  private headers() { return { "X-API-Key": this.key, "Content-Type": "application/json" }; }

  assets() {
    return fetch(`${BASE}/v1/assets`).then((r) => r.json());
  }

  quotes(q: Record<string, string>) {
    return fetch(`${BASE}/v1/partner/quotes?${new URLSearchParams(q)}`, {
      headers: this.headers(),
    }).then((r) => r.json());
  }

  createOrder(body: object, idempotencyKey: string) {
    return fetch(`${BASE}/v1/partner/orders`, {
      method: "POST",
      headers: { ...this.headers(), "Idempotency-Key": idempotencyKey },
      body: JSON.stringify(body),
    }).then((r) => r.json());
  }

  order(id: string) {
    return fetch(`${BASE}/v1/partner/orders/${id}`, { headers: this.headers() })
      .then((r) => r.json());
  }
}

Кода чуть больше стоит только стриминг — именно он делает интерфейс мгновенным:

const res = await fetch(sseURL, {
  headers: { "X-API-Key": key, Accept: "text/event-stream" },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
// делите поток по "\n\n", читайте строки "event:" / "data:" и рисуйте каждый
// `offer` по мере прихода. `done` закрывает поток и приносит финальную карту
// `deviations` — переранжируйте уже нарисованное, а не ждите её, чтобы рисовать.

Как это становится виджетом

Виджет живёт на чужой странице — ровно там, где ключа быть не должно. Рабочая схема такая:

виджет в браузереваш бэкенд (добавляет X-API-Key)api.swapzilla.io
  • Проксируйте все вызовы с ключом. API отвечает с Access-Control-Allow-Origin: *, то есть браузер может ходить напрямую — и тогда ключ виден любому в DevTools.
  • Пробрасывайте поток как есть. Прокси может передавать text/event-stream без изменений: виджет сохраняет живые цены, ни разу не увидев ключ.
  • Кэшируйте котировки на 5–10 секунд. На нашей стороне лимитов нет, но провайдеры начинают троттлить повторные котировки гораздо раньше, чем это заметят пользователи.
  • Показывайте, между чем выбирает пользователь. В предложении есть ProviderName, EstimatedMins, KycRating (от A до D) и DeviationPercent: самое дешёвое предложение — не всегда нужное.
  • Проверяйте адрес получения через /v1/validate-address до того, как кнопка станет активной. Вызов без ключа, так что виджет может делать его сам.

Что даёт API, а что пишете вы

SwapZilla даётВы пишете
Предложения всех подключённых обменников, отранжированные, одним запросомИнтерфейс, в котором они рисуются
Создание ордеров, депозитные адреса и статус до зачисленияПрокси, который хранит ключ
Актуальные списки активов, сетей и провайдеровСобственный кэш на 5–10 секунд
Идемпотентность, адреса возврата, защиту от проскальзыванияХранение связки с вашим client_order_id
Ссылку для поддержки (ProviderOrderID) на каждый ордерПервую линию поддержки своих пользователей

Чего нет — чтобы никто на это не рассчитывал: опубликованного SDK-пакета, готовой сборки виджета, вебхуков и продакшн-песочницы. Для детерминированных smoke-тестов вместо неё можно включить на ваш ключ провайдер mock.

Кто это встраивает

  • Кошельки, которым нужен обмен без кастодиального хранения, ликвидности и разговора про лицензию.
  • Telegram-боты и мини-приложения: весь обменник — это четыре экрана, а ключ спокойно лежит на сервере бота.
  • Агрегаторы и мониторинги, которые могут читать ещё и /v1/export/rates.xml напрямую.
  • Портфельные трекеры и дашборды, превращающие «у вас перевес в ETH» в обмен, который пользователь принимает не выходя из экрана.

Вопросы

Есть ли официальный SDK SwapZilla?

В виде опубликованного пакета — нет. Partner API — это обычный JSON поверх HTTP с одним заголовком, и полноценный клиент умещается примерно в тридцать строк на любом языке. Справочник на /ru/developers/ описывает каждый эндпоинт, поле и статус, так что клиент пишется сразу по нему. Ближайший разобранный пример — открытый сервер swapzilla-mcp: небольшой JavaScript-клиент на шесть операций под лицензией MIT, читается за один присест.

Может ли виджет ходить в API прямо из браузера?

Технически да — API отдаёт Access-Control-Allow-Origin: *, — но не с вашим ключом. Ключ это bearer-credential: кто им владеет, тот торгует от вашего имени. Вызовы с ключом проксируйте через свой бэкенд и заголовок добавляйте там. Эндпоинты без ключа (/v1/assets, /v1/providers, /v1/validate-address) можно звать напрямую.

Насколько быстрые котировки?

По /v1/partner/quotes-sse первое предложение обычно приходит за 200–400 мс, а поток закрывается сам по timeout_ms — по умолчанию и максимум 5000 мс. Обычный /quotes ждёт самого медленного провайдера, который успевает ответить в это окно.

Есть ли ограничения по частоте запросов?

На стороне SwapZilla — нет. Провайдеры троттлят повторные котировки, поэтому кэшируйте котировки на 5–10 секунд, опрашивайте ордера не чаще раза в 5 секунд и вызывайте синхронный refresh максимум раз в пять секунд.

Можно ли полностью white-label?

Да. Ни один шаг не требует интерфейса или бренда SwapZilla: предложения, экран депозита и таймлайн статусов рисуете вы. Каждый вызов с вашим ключом помечается вашим partner id, и вы видите только свои ордера.

Что такое приватные обмены?

Приватный обмен разрывает ончейн-связь между отправителем и получателем, проводя средства через промежуточный анонимный актив — по умолчанию Monero — двумя связанными ордерами под одним PrivateSwapID. Маршруты, где оба плеча идут через одного провайдера, отбрасываются. Пользователю показывается FirstOrder.DepositAddress.

Что ещё собирают на этом же ключе

Как получить ключ

Зарегистрируйтесь в партнёрском кабинете — партнёрский id и api_key для заголовка X-API-Key выпускаются сразу. Ключ становится рабочим после активации: напишите в @swapzilla_support_bot и коротко опишите интеграцию. Все эндпоинты, поля и статусы — в документации partner API.