Авторизація агентів
Підтримка підпису кількома ключами для маркетмейкерів.
Огляд
Авторизація агентів дозволяє окремому ключу підпису (агенту) розміщувати та скасовувати ордери від імені торгового гаманця. Це корисно для:
- Безпеки: ключі торгового гаманця зберігаються в холодному сховищі, а для підпису використовуються гарячі ключі
- Операційної роботи: кілька членів команди можуть підписувати різними ключами
- Автоматизації: автоматизовані системи можуть підписувати окремими ключами
Дві моделі авторизації
Hypercall має дві окремі системи делегування залежно від продукту:
| Продукт | Тип делегування | Зберігання | Як налаштувати |
|---|---|---|---|
| Опціони (REST API) | Авторизація агентів | Стан рушія Hypercall | POST /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 приймається, якщо:
!stored_set.contains(nonce): він не є дублікатомnonce > min(stored_set), коли набір містить 100 записів: він більший за найменший збережений noncenonceперебуває в межах (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..."
]
}
Примітки:
- Повертає лише активних агентів, термін дії яких не минув
Використання агентів
Підпис ордерів агентом
Після схвалення агента:
- Підпишіть ордер гаманцем агента: використовуйте гаманець агента для підпису повідомлень
PlaceOrder/CancelOrder - Заповніть поле wallet: вкажіть у полі
walletадресу торгового гаманця (не адресу агента) - Перевірка проміжним ПЗ: проміжне ПЗ перевіряє, що агент авторизований для цього гаманця
Приклад:
// 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 /orderDELETE /orderDELETE /order_cloid
Перевірка: signature_and_agent_middleware перевіряє:
- Відновлення підпису успішне
- Підписант авторизований (signer == wallet АБО агент авторизований)
Обробник (пакетні ордери)
Ендпоінти:
POST /bulk_orderDELETE /bulk_orderDELETE /bulk_order_cloid
Перевірка: перевірка кожного елемента в обробнику:
- Відновлення підпису для кожного елемента
- Перевірка авторизації агента для кожного елемента
Зберігання авторизацій
Авторизація агентів є станом, яким володіє рушій. Команди ApproveAgent і RevokeAgent журналюються, відновлюються через повторне відтворення рушія та надаються через знімок для читання для перевірок API.
Логіка авторизації
Авторизація підписанта є явною логікою АБО:
- Прямий підпис:
signer == wallet. - Підпис агентом: знімок рушія містить запис авторизації для
wallet_address == <wallet>іagent_address == <signer>, аexpires_atвідсутній або вказує на майбутнє.
Термін дії
Рушій підтримує expires_at для авторизації та вважає агента з простроченою
авторизацією неавторизованим. POST /approve-agent не встановлює це поле, тому агенти,
схвалені через API, залишаються активними до відкликання.
Міркування щодо безпеки
- Безпека ключів агентів: захищайте приватні ключі агентів (використовуйте апаратні гаманці або захищене керування ключами)
- Регулярні аудити: регулярно переглядайте авторизованих агентів через
GET /authorized-agents - Відкликайте невикористовуваних агентів: відкликайте агентів, які більше не потрібні
Найкращі практики
- Використовуйте агентів для автоматизації: зберігайте ключі торгового гаманця в холодному сховищі, а для автоматизованих систем використовуйте агентів
- Обмежуйте доступ агентів: схвалюйте лише тих агентів, яким потрібен доступ
- Відстежуйте використання агентів: стежте, які агенти розміщують ордери
- Відкликайте вчасно: відкликайте агентів одразу, щойно вони більше не потрібні
Поширені проблеми
"Signer 0x... is not authorized to act for wallet 0x..."
Причина: агента не схвалено або термін дії авторизації минув чи її відкликано.
Рішення: схваліть агента через POST /approve-agent або підписуйте безпосередньо гаманцем.
Авторизація агента не працює
Причини:
- Агент відсутній у стані авторизації, яким володіє рушій
- Авторизацію було відкликано
- Термін дії авторизації минув
Рішення: перевірте статус агента через GET /authorized-agents?wallet=....