Цю сторінку перекладено автоматично. Оригінал англійською мовою є канонічним. Читати англійською
Перейти к основному содержимому

Авторизація агентів

Підтримка підпису кількома ключами для маркетмейкерів.

Огляд

Авторизація агентів дозволяє виділеному ключу підпису (агенту) розміщувати та скасовувати заявки від імені торгового гаманця. Це корисно для:

  • Безпеки: тримайте ключі торгового гаманця в холодному сховищі, використовуйте гарячі ключі для підпису
  • Операційної діяльності: кілька членів команди можуть підписувати різними ключами
  • Автоматизації: автоматизовані системи можуть підписувати виділеними ключами

Дві моделі авторизації

Hypercall має дві окремі системи делегування залежно від продукту:

ПродуктТип делегуванняЗберіганняЯк налаштувати
Опціони (REST API)Авторизація агентаПоза ланцюгом (база даних)POST /approve-agent
Перпи (ончейн-директиви)API-гаманецьОнчейн (контракт Exchange)Директива hc_update_api_wallet

Це незалежні системи. Схвалення агента для торгівлі опціонами не авторизує його для перпів, і навпаки.

Опціони: авторизація агента (поза ланцюгом)

Агенти підписують EIP-712-повідомлення PlaceOrder та CancelOrder від імені торгового гаманця. API-сервер перевіряє авторизацію за своєю базою даних перед пересиланням до рушія.

Перпи: API-гаманець (ончейн)

API-гаманці підписують директиви перпів, використовуючи EIP-712-домен HypercallAgentSign. Контракт Exchange перевіряє авторизацію ончейн через isApiWalletActive(). Див. Підписання EIP-712 для повного довідника з підписання директив.

Щоб додати або видалити API-гаманець, надішліть директиву hc_update_api_wallet, підписану гаманцем-менеджером акаунта.

Це відображає модель API-гаманців Hyperliquid. Hyperliquid документує їх як API-гаманці, також відомі як агентські гаманці, у розділі Nonces and API wallets, а approveAgent документовано в Exchange endpoint.

Захист від повторного використання nonce

Відстеження nonce слідує моделі nonce Hyperliquid. Усі підписані дії (заявки, схвалення/відкликання агентів, QP-хендшейки) використовують спільний простір nonce для кожного підписанта. Рушій зберігає 100 найбільших nonce для кожної адреси підписанта. Новий nonce приймається, якщо:

  1. nonce > min(stored_set) -- має бути більшим за найменший збережений nonce
  2. !stored_set.contains(nonce) -- не повинен бути дублікатом
  3. nonce знаходиться в межах (T - 2 дні, T + 1 день) від часової мітки сервера

Nonce поза порядком дозволені (наприклад, nonce 105, а потім 102 — обидва спрацюють, якщо обидва більші за мінімум набору). Набір обмежений 100 записами, тому найстаріші записи витісняються при додаванні нових. Це запобігає блокуванню акаунта через один великий nonce.

Підписант nonce — це адреса, яка підписала EIP-712-повідомлення: API-гаманець для заявок, відновлений підписант для авторизації агента, QP-гаманець для хендшейків. Клієнтам слід використовувати Date.now() (мілісекундна епоха) як початкове значення nonce та збільшувати його монотонно.

Авторизація агентів для опціонів

Пряме підписання

Якщо signer == wallet, заявка завжди авторизована (самопідписання).

Підписання агентом

Якщо signer != wallet, підписант має бути авторизованим агентом:

  • Агент має бути присутнім у стані авторизації, що належить рушію
  • Авторизація не повинна бути простроченою
  • Знімки рушія та журнал рушія є надійними джерелами для відновлення після перезапуску

Схвалення агента

Ендпоінт: POST /approve-agent

Запит: ApproveAgentRequest

{
"agent": "0x...",
"nonce": 1,
"signature": "0x..."
}

Підписання:

  • Власник гаманця підписує повідомлення ApproveAgent
  • Гаманець визначається з відновленого підпису
  • Агент — це поле agent у запиті

Структура EIP-712:

struct ApproveAgent {
address agent;
uint64 nonce;
}

Відповідь: ApproveAgentResponse

{
"success": true,
"error": null
}

Примітки:

  • Авторизація агента є постійною (зберігається в БД)
  • Авторизація не закінчується, якщо не встановлено expires_at (ще не реалізовано)

Відкликання агента

Ендпоінт: DELETE /revoke-agent

Запит: RevokeAgentRequest

{
"agent": "0x...",
"nonce": 2,
"signature": "0x..."
}

Підписання:

  • Власник гаманця підписує повідомлення RevokeAgent
  • Гаманець визначається з відновленого підпису

Структура EIP-712:

struct RevokeAgent {
address agent;
uint64 nonce;
}

Відповідь: RevokeAgentResponse

Примітки:

  • Застосовує журнальовану команду RevokeAgent до стану авторизації, що належить рушію
  • Перевірки авторизації торгового API читають стан бекенду та застосовують відкликання для торгових запитів. Публікація в trollbox може кешувати позитивну авторизацію агента довше, тому нещодавно відкликаний агент усе ще може публікувати повідомлення, поки цей кеш не закінчиться або best-effort інвалідація не досягне відповідної edge-локації. Цей кеш не авторизує мутації торгового API.
  • Агент більше не може підписувати для гаманця після відкликання

Отримання авторизованих агентів

Ендпоінт: GET /authorized-agents?wallet=...

Параметри запиту:

  • wallet (обов'язковий)

Відповідь:

{
"agents": [
"0x...",
"0x..."
]
}

Примітки:

  • Повертає лише активних, непрострочених агентів
  • Впорядковано за created_at DESC

Використання агента

Підписання заявок агентом

Після схвалення агента:

  1. Підпишіть заявку гаманцем агента: використовуйте гаманець агента для підписання повідомлень PlaceOrder / CancelOrder
  2. Встановіть поле wallet: встановіть поле wallet на адресу торгового гаманця (не адресу агента)
  3. Перевірка middleware: middleware перевіряє, що агент авторизований для цього гаманця

Приклад:

// Agent wallet signs the order
const agentSigner = new ethers.Wallet(agentPrivateKey);

const message = {
wallet: "0x...", // Trading wallet (not agent)
symbol: "BTC-20250131-100000-C",
side: "Buy",
size: "0.1",
price: "100.0",
tif: "gtc",
clientId: "mm-1",
nonce: 1
};

// Sign with agent wallet
const signature = await agentSigner._signTypedData(domain, types, message);

// Send request
const response = await fetch('/order', {
method: 'POST',
body: JSON.stringify({
...message,
signature
})
});

Пакетні заявки з агентом

Пакетні ендпоінти перевіряють авторизацію агента для кожного елемента:

  • Кожна заявка в POST /bulk_order може бути підписана іншим агентом
  • Авторизація агента перевіряється для кожного елемента окремо
  • Якщо будь-який елемент не проходить авторизацію агента, цей елемент повертає помилку в BulkOrderResult

Перевірки авторизації

Middleware (одиночні заявки)

Ендпоінти:

  • POST /order
  • DELETE /order
  • DELETE /order_cloid

Перевірка: signature_and_agent_middleware перевіряє:

  1. Відновлення підпису успішне
  2. Підписант авторизований (signer == wallet АБО агент авторизований)

Обробник (пакетні заявки)

Ендпоінти:

  • POST /bulk_order
  • DELETE /bulk_order
  • DELETE /bulk_order_cloid

Перевірка: поелементна перевірка в обробнику:

  1. Відновлення підпису для кожного елемента
  2. Перевірка авторизації агента для кожного елемента

Зберігання авторизації

Авторизація агентів — це стан, що належить рушію. Команди ApproveAgent та RevokeAgent журналюються, відновлюються через реплей рушія та надаються через знімок для читання для перевірок API.

Логіка авторизації

Авторизація підписанта — це явна логіка АБО:

  • Пряме підписання: signer == wallet.
  • Підписання агентом: знімок рушія містить запис авторизації для wallet_address == <wallet> та agent_address == <signer>, а expires_at відсутній або в майбутньому.

Закінчення терміну дії

expires_at застосовується перевірками авторизації знімка рушія. Агенти з expires_at < NOW() вважаються неавторизованими.

Міркування безпеки

  1. Безпека ключів агентів: захищайте приватні ключі агентів (використовуйте апаратні гаманці або безпечне управління ключами)
  2. Регулярні аудити: регулярно переглядайте авторизованих агентів через GET /authorized-agents
  3. Відкликайте невикористовуваних агентів: відкликайте агентів, які більше не потрібні
  4. Термін дії: використовуйте expires_at для тимчасових авторизацій агентів, коли шлях схвалення надає нестандартний термін дії

Найкращі практики

  1. Використовуйте агентів для автоматизації: тримайте ключі торгового гаманця в холодному сховищі, використовуйте агентів для автоматизованих систем
  2. Обмежуйте область дії агентів: схвалюйте лише тих агентів, яким потрібен доступ
  3. Відстежуйте використання агентів: відстежуйте, які агенти розміщують заявки
  4. Відкликайте оперативно: відкликайте агентів негайно, коли вони більше не потрібні

Поширені проблеми

«Unauthorized: signer not authorized for wallet»

Причина: агент не схвалений або авторизація прострочена/відкликана.

Рішення: схваліть агента через POST /approve-agent або підпишіть безпосередньо гаманцем.

Авторизація агента не працює

Причини:

  • Агент відсутній у стані авторизації, що належить рушію
  • Авторизацію було відкликано
  • Авторизація прострочена

Рішення: перевірте статус агента через GET /authorized-agents?wallet=....