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

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

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

Огляд​

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

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

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

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

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

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

Опціони: авторизація агентів (офчейн)​

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

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

API-гаманці підписують ордери та скасування для перпів у EIP-712 домені HypercallApiSign. Hypercall перевіряє підписанта за вашим контрактом Account (isApiWalletActive()), перш ніж прийняти ордер. На маршруті TEE (типовий у застосунку та доступний за бажанням для API-клієнтів) захищений анклав, який зберігає окремий торговий ключ Hyperliquid для вашого Account, підписує та надсилає нативний ордер; на маршруті смарт-контракту, що є розширеним налаштуванням у застосунку, ордер проходить через ваш контракт Account. Довідку з підпису див. у EIP-712 Signing, а опис процесу у Perps.

Щоб додати або видалити 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. !stored_set.contains(nonce): він не є дублікатом
  2. nonce > min(stored_set), коли набір містить 100 записів: він більший за найменший збережений 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
}

Примітки:

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

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

Ендпоінт: 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.
  • Після відкликання агент більше не може підписувати від імені гаманця

Відкликання всіх агентів​

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

Запит: { "nonce": 3, "signature": "0x..." }, підписаний власником гаманця над RevokeAllAgents(uint64 nonce). Видаляє всіх агентів для відновленого гаманця.

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

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

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

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

Відповідь:

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

Примітки:

  • Повертає лише активних агентів, термін дії яких не минув

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

Підпис ордерів агентом​

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

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

Приклад:

// 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. The REST body uses snake_case `client_id`.
const { clientId, ...rest } = message;
const response = await fetch('/order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...rest,
client_id: clientId,
signature
})
});

Пакетні ордери з агентом​

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

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

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

Проміжне ПЗ (окремі ордери)​

Ендпоінти:

  • 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 для авторизації та вважає агента з простроченою авторизацією неавторизованим. POST /approve-agent не встановлює це поле, тому агенти, схвалені через API, залишаються активними до відкликання.

Міркування щодо безпеки​

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

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

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

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

"Signer 0x... is not authorized to act for wallet 0x..."​

Причина: агента не схвалено або термін дії авторизації минув чи її відкликано.

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

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

Причини:

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

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