Multi-send

Multi-send: массовые выплаты на множество адресов

CSV с получателями превращается в набор независимых ордеров — кросс-чейн, каждый в том активе, который нужен получателю. Один адрес, не прошедший минимум провайдера, не блокирует остальные четыреста.

  • На получателясвоя котировка, адрес и статус
  • Кросс-чейнсвой актив у каждого получателя
  • Модель отказапо получателю, не по всей выгрузке
  • ПовторыIdempotency-Key, без двойной отправки

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

Пакет — это не одна транзакция, а множество независимых ордеров, которые просто стартуют вместе. У каждого получателя своя котировка, свой депозитный адрес и свой статус, поэтому список выплат свободно пересекает сети и активы, а одна плохая строка не задерживает остальные.

  • Получателям в одном запуске можно платить разными активами и в разных сетях.
  • Отказ — по получателю: сумма ниже минимума отклоняется при создании ордера, до движения денег.
  • Idempotency-ключи делают повторный прогон после сбоя безопасным.
  • Никакого ончейн-контракта multisend и никакого общего баланса.

От CSV до закрытого запуска

  1. Проверьте список до того, как считать котировки

    Каждая строка — адрес, актив, сеть, сумма. Прогоните их через GET /v1/validate-address (вызов без ключа) и отклоняйте файл, а не выплату. known:false означает, что для сети нет шаблона проверки: это «не проверено», а не «верно».

  2. Котировка каждой строки

    По одной котировке на получателя, по сумме к получению (amount_to). Сумма возвращённых FromAmount — это стоимость запуска; согласуйте её до того, как что-то создано.

  3. Создавайте ордера небольшими партиями

    Пять–десять параллельных созданий — правильный темп: провайдеры троттлят всплески, а каждый ордер нужно успеть создать и оплатить за пять минут жизни предложения. В каждом создании — Idempotency-Key из идентификатора запуска и строки.

  4. Оплатите каждый ордер

    У каждого свой DepositAddress и точная сумма AmountFrom. Здесь и живут комиссии сети: сто получателей — сто исходящих переводов с вашего кошелька.

  5. Соберите результаты

    Опросите ордера до финального статуса и напишите отчёт по запуску: DONE с TxID — или причина и строка на повтор.

Веерная отправка

import pLimit from "p-limit";
const limit = pLimit(8);                      // провайдеры не любят всплески

const results = await Promise.all(rows.map((row, i) => limit(async () => {
  try {
    const order = await createPayout(runID, row, i);   // котировка → POST /orders
    return { row: i, ok: true, id: order.ID, send: order.AmountFrom,
             to: order.DepositAddress };
  } catch (e) {
    return { row: i, ok: false, error: String(e) };    // одна строка, а не весь запуск
  }
})));

const payable = results.filter((r) => r.ok);
const rejected = results.filter((r) => !r.ok);         // покажите их до оплаты

Перезапускаемым запуск делает именно idempotency-ключ. Стройте его из запуска и строки, но не из часов:

const key = `${runID}:${row.address}:${row.amount}`;  // не меняется при повторах
// POST /v1/partner/orders с заголовком "Idempotency-Key: "
// Повтор вернёт тот же ордер — упавший запуск продолжится, а не задвоится.

Когда строка не проходит

Что вы видитеПочемуЧто делать
400, сумма ниже минимумаСтрока меньше MinFromAmount провайдера для этой пары.Сверяйте MinFromAmount на котировке; объединяйте мелкие суммы в более крупные выплаты или меняйте актив.
400 offer expiredМежду котировкой и созданием прошло больше пяти минут.Пересчитайте строку. Держите цепочку котировка → ордер → оплата плотной.
400 provider is disabledОбменник отключили уже после котировки.Пересчитайте: следующее предложение придёт от другого провайдера.
Предложений нет вовсеЭту пару сейчас никто не обслуживает.Заплатите этому получателю активом, который есть в /v1/assets.
TIME_EXPIRED после пропущенной оплатыДепозит не пришёл в окно провайдера.Пересчитайте и создайте заново: ничего не отправлено — ничего не потеряно.
REFUNDEDОбмен не удался уже после оплаты.Провайдер вернёт монеты на refund_address — всегда указывайте там свой кошелёк.

Чем это отличается от ончейн-multisend

Контракт multisendПакет SwapZilla
СетиОдна, в которой живёт контрактЛюбая пара, которую покрывают провайдеры, вперемешку в одном запуске
АктивыТот, что у вас уже естьСвой у каждого получателя — конвертация по пути
ТранзакцииОдна, дёшево в пересчёте на получателяОдин депозит на получателя — цена отказа от общего котла
КастодиальностьНетНет
ОтказОбычно всё или ничегоПо получателю, с причиной

Чего нет и что стоит учесть заранее: единого batch-эндпоинта, одной оплачивающей транзакции, вебхуков и фиатного плеча. Запуск — это цикл на вашей стороне; API делает безопасной каждую его итерацию.

Что рассылают веером

  • Партнёрские и реферальные выплаты — сотни небольших сумм, каждая в том активе, который попросил партнёр.
  • Программы для авторов и баунти, где список меняется каждый цикл, а адреса приходят от пользователей.
  • Аирдропы и вознаграждения, которые должны прийти в предпочитаемой получателем сети, а не в вашей.
  • Возвраты и компенсации, которые сверяются построчно по TxID.

Вопросы

Есть ли один эндпоинт, принимающий список получателей?

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

Можно отправить на сто адресов в разных сетях за один запуск?

Да. В каждом ордере свои актив и сеть получения, поэтому один запуск может закрыть USDT TRC20, BTC и ETH одновременно из одного исходного актива. Общим остаётся только идентификатор запуска, который вы кладёте в client_order_id каждого ордера.

Что мешает упавшему запуску заплатить дважды при перезапуске?

Стабильный Idempotency-Key на строку — собранный из идентификатора запуска и получателя, а не из времени. Повторное создание с тем же ключом вернёт уже существующий ордер, а не откроет второй.

Сколько ордеров можно создавать одновременно?

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

Кто платит комиссии сети?

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

Можно ли посмотреть весь запуск потом?

GET /v1/partner/orders?page=1&limit=100 отдаёт ваши ордера свежими вперёд и постранично, и в каждом есть заданный вами client_order_id — запуск собирается обратно по вашему же префиксу. Отдельный ордер можно синхронно обновить через POST /v1/partner/orders/{id}/refresh.

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

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

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