Підпис EIP-712
Ця сторінка є довідником на рівні полів для кожного повідомлення EIP-712, яке перевіряє Hypercall: три домени підпису директив (API-гаманець, Manager, RSM), повідомлення для перпів, що існують лише поза ланцюгом і використовують домен API-гаманця, а також окремий домен Physical Covered Call Quote. Ордери на опціони через REST API використовують інший домен, Hypercall; див. Автентифікація та підпис.
Усе тут перевірено на контрактах, розгорнутих в основній мережі HyperEVM (chain ID 999): Exchange 0.6.1 за адресою 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 і Account 0.2.4. Наведені нижче роздільники доменів і typehash вбудовані в цей розгорнутий байткод.
Огляд
Директива є однією дією щодо одного Account, яку підписують поза ланцюгом, а секвенсер Hypercall надсилає в ланцюг через Exchange.executeUserDirective або Exchange.executeRsmDirective. Account відновлює підписанта з дайджесту EIP-712 і перевіряє авторизацію:
- API-гаманець: адреса, зареєстрована в Account через
hc_update_api_wallet(Account.isApiWalletActive). Підписує ордери та скасування. - Manager: власник Account (
Account.manager). Підписує зміни API-гаманців, надсилання активів і зміни режиму акаунта. - Підписант RSM: контролюється протоколом (
Exchange.rsmSigner). Підписує зарахування, виведення, директиви ліквідації та відновлювальні ордери reduce-only. Користувачі ніколи їх не підписують.
Кодування директиви
У ланцюгу директива має вигляд abi.encodePacked(account, nonce, version, id, data):
| Байти | Поле | Значення |
|---|---|---|
| 20 | account | Адреса Account (address) |
| 8 | nonce | Nonce підписанта (uint64) |
| 1 | version | Сімейство дій |
| 3 | id | ID дії в межах сімейства |
| решта | data | abi.encode внутрішньої структури дії |
| Версія | Сімейство | ID дій |
|---|---|---|
0 | HyperCall (HC) | 2 оновлення API-гаманця. 1 (переказ опціону) зарезервовано й відхиляється. |
1 | HyperLiquid (HL) | 1 лімітний ордер, 9 додавання API-гаманця, 10 скасування за oid, 11 скасування за cloid, 13 надсилання активу, 16 встановлення абстракції |
255 | System | 1 зарахування токена, 2 зарахування опціону, 3 початок ліквідації, 4 зупинка ліквідації, 5 виведення токена |
Вам не потрібно самостійно формувати цей рядок байтів. Підпишіть типізовані дані, а потім надішліть account, nonce, action і signature до API, який закодує директиву.
Форма типізованих даних
Кожна директива має однакову зовнішню форму: адреса Account, nonce підписанта й одна внутрішня структура дії.
<Outer>(address account,uint64 nonce,<Inner> action)<Inner>(...)
Зовнішній рядок типу доповнюється визначенням внутрішнього типу, тож typehash охоплює обидва. У термінах EIP-712 primaryType є зовнішньою назвою, types містить обидва записи, а message має вигляд { account, nonce, action }. Порядок полів є частиною рядка типу й має збігатися точно.
Непідписані точки входу для поповнення
Не кожен виклик поповнення є дією EIP-712. Ці методи є прямими транзакціями, які надсилає гаманець-платник або роутер:
function depositUsdcFor(address account, uint256 amount) external;
function depositOption(address account, address token, uint256 amount) external;
depositUsdcFor навмисно не підписується, оскільки msg.sender є лише платником USDC. Акаунт Hypercall, якому зараховуються кошти, вказується явним аргументом account і полем події UsdcDeposit.account. Роутери та zap-контракти можуть викликати цей метод, тому індексатори й бекенд-сервіси не повинні використовувати msg.sender для визначення одержувача зарахування.
depositOption спалює опціонні токени з msg.sender і генерує Deposit(account, msg.sender, token, amount) для індексатора RSM. Шлях зарахування опціонів керується подіями й не використовує підпис менеджера, агента чи RSM від вкладника.
Окремий домен: котирування фізичних покритих коллів
Котирування фізичних покритих колл-опціонів перевіряє фабрика, розгорнута в обраному ланцюгу. Вони не використовують верифікатор Exchange або його домен з нульовою адресою.
Домен:
{
"name": "Hypercall Physical Covered Call",
"version": "1",
"chainId": "<selected chain id>",
"verifyingContract": "<exact PhysicalCoveredCallFactory address>"
}
Підписант: маркетмейкер, закодований у PhysicalCoveredCallQuote.marketMaker.
Канонічні вкладені типи:
AssetTerms(address underlyingWrapper)
OptionTerms(address seller,uint256 underlyingAmount,uint64 strikeX8,uint64 expiry)
PhysicalCoveredCallRequest(bytes32 rfqId,AssetTerms asset,OptionTerms option)AssetTerms(address underlyingWrapper)OptionTerms(address seller,uint256 underlyingAmount,uint64 strikeX8,uint64 expiry)
PhysicalCoveredCallQuote(bytes32 requestHash,bytes32 quoteId,address marketMaker,uint256 premiumSettlement,uint64 quoteDeadline,uint64 nonce)
Фабрика заново обчислює requestHash з повного вкладеного запиту, перш ніж відновити підписанта котирування. Отже, підпис фіксує продавця, обгортку базового активу, кількість часток обгортки, страйк, експірацію, премію, дедлайн котирування, nonce, chain id та адресу фабрики. Токен розрахунку та його десяткові знаки є авторитетною конфігурацією фабрики, а не окремо підписаними значеннями. Pyth у цьому поколінні без оракулів відсутній. Коли продавець фінансує сховище, використовуються і дайджест котирування, і nonce маркетмейкера.
Надіслати підписане котирування може лише продавець, закодований у запиті. Фінансування мінтить NFT права вимоги райтера продавцю, а NFT довгої позиції за опціоном маркетмейкеру з котирування, за умови що цей маркетмейкер є допустимим одержувачем, поки увімкнено необов'язковий білий список покупців. Дійсний підпис авторизує фінансування, а не виконання.
Викликати виконання може лише поточний власник NFT довгої позиції за опціоном. Це правило «лише власник» не дає оператору ERC-721 використати дозвіл власника на витрату токена розрахунку. Схвалений оператор усе ще може передати NFT за стандартними правилами ERC-721, що передає економічне право допустимому одержувачу, поки увімкнено обмеження для покупців. Успішне виконання стягує кошти за страйком з власника, що викликає функцію, передає йому базовий актив і спалює NFT довгої позиції за опціоном.
Роздільники доменів EIP-712
Три домени директив мають однакову структуру й відрізняються лише name. verifyingContract є нульовою адресою, тож той самий підпис дійсний для будь-якого Account у ланцюгу, а прив'язку до одного Account забезпечує адреса Account усередині повідомлення.
{
"name": "<DomainName>",
"version": "1",
"chainId": <chainId>,
"verifyingContract": "0x0000000000000000000000000000000000000000"
}
Тип домену: EIP712Domain(string name,string version,uint256 chainId,address verifyingContract).
Chain ID: основна мережа 999, тестнет 998. Account обирає роздільник за ланцюгом, у якому працює, тож підпис із тестнету ніколи не пройде перевірку в основній мережі.
| Домен | name | version | Підписант | Ланцюг | Роздільник |
|---|---|---|---|---|---|
| API-гаманець | HypercallApiSign | 1 | API-гаманець | 999 | 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb |
| API-гаманець | HypercallApiSign | 1 | API-гаманець | 998 | 0x339bee4c00da9a5361f687797205c8d03f323659f5d9dc9e0505b9437ddee25e |
| Manager | HypercallManagerSign | 1 | Manager | 999 | 0xc9b5b0b8b0d9d7ba716326acbf795cfe431ef960a25a8f958d6569bea2f1516e |
| Manager | HypercallManagerSign | 1 | Manager | 998 | 0xd1f76b6138be892c14b71b0569bdb049cb44f239d34c78ef1ffaacd2466f9f18 |
| RSM | HypercallRsmSign | 1 | Підписант RSM | 999 | 0x3d0cae2af623c614099dbadd67a1e1457fabde576aa270a70a57e39bf338a7be |
| RSM | HypercallRsmSign | 1 | Підписант RSM | 998 | 0x650b282053fb61d3fd477bdc28f6434311fe905e27cc4ca643e87e802c45938c |
Перш ніж щось підписувати, обчисліть роздільник самостійно й порівняйте:
import { ethers } from "ethers";
const separator = ethers.TypedDataEncoder.hashDomain({
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
});
// 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb
Довідник повідомлень
Матриця підписантів і ендпоінтів
| Повідомлення | Домен | Підписант | Куди надсилати | Що виконує |
|---|---|---|---|---|
HLOrder | API | API-гаманець | POST /v1/tee-perp/orders/submit або POST /v1/actions/hl_limit_order | Лімітний ордер Hyperliquid |
HLCancel | API | API-гаманець | POST /v1/tee-perp/cancels/submit-by-oid або POST /v1/actions/hl_cancel_by_oid | Скасування за oid |
HLCancelByCloid | API | API-гаманець | POST /v1/tee-perp/cancels/submit або POST /v1/actions/hl_cancel_by_cloid | Скасування за cloid |
HCPerpTriggerOrder | API | API-гаманець | POST /v1/tee-perp/orders/submit-trigger | Нативний тригерний ордер (лише TEE) |
HCPerpOrderBatch | API | API-гаманець | POST /v1/tee-perp/orders/submit-batch | Нативний пакет ордерів (лише TEE) |
HCPerpLeverageChange | API | API-гаманець | POST /v1/tee-perp/leverage/submit | Оновлення кредитного плеча (лише TEE) |
HCPerpScheduleCancel | API | API-гаманець | POST /v1/tee-perp/schedule-cancel/submit | Перемикач «мертвої руки» (лише TEE) |
HCUpdateApiWallet | Manager | Manager | POST /v1/actions/hc_update_api_wallet | Реєстр API-гаманців Account |
HLAddApiWallet | Manager | Manager | POST /v1/actions/hl_add_api_wallet | Схвалення API-гаманця на HyperCore |
HLSendAsset | Manager | Manager | POST /v1/actions/hl_send_asset | sendAsset на HyperCore з Account |
HLSetAbstraction | Manager | Manager | POST /v1/actions/hl_set_abstraction | Режим акаунта на HyperCore (лише unified) |
HCTransferOption | Manager | Manager | Не приймається | Зарезервовано, відхиляється в ланцюгу |
HLOrder, HLCancel, HLCancelByCloid, HLSendAsset | RSM | Підписант RSM | Лише секвенсер | Відновлювальні ордери та перекази через Account |
System* | RSM | Підписант RSM | Лише секвенсер | Зарахування, виведення, ліквідація через Exchange |
Усі маршрути /v1/actions/{action} приймають account, nonce, action і signature. POST /v1/actions/{action}/typed-data повертає точні типізовані дані для підпису цього запиту, і це найпростіший спосіб перевірити ваш енкодер. GET /v1/directives/{directive_id} повідомляє результат у ланцюгу. Схеми запитів наведено в Довіднику API.
Формат передавання
nonceі кожне полеuint64,uint128абоuint256є цілими числами JSON до9007199254740991або десятковими рядками. Для більших значень використовуйте рядки.signatureє 65-байтовим hex-рядком з0x(r || s || v).vможе бути0,1,27або28.- Поля
bytes32є 32-байтовим hex з префіксом0x. Адреси подаються в hex з контрольною сумою або в нижньому регістрі. - Ціни та розміри перпів є цілими числами HyperCore з множником
1e8, наприклад$50,000це5000000000000, а0.001монети це100000.
Директиви API-гаманця (HypercallApiSign)
Підписуються активним API-гаманцем Account. Використовуйте chain ID 999, name HypercallApiSign.
Тестові вектори використовують умовний акаунт і фіксований nonce, щоб ви могли побайтово перевірити свій енкодер. Дайджест: keccak256(0x1901 || domainSeparator || directiveStructHash).
HLOrder
Один лімітний ордер Hyperliquid для Account.
Структура:
struct LimitOrder {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint128 cloid;
}
struct HLOrder {
address account;
uint64 nonce;
LimitOrder action;
}
Канонічний тип EIP-712:
HLOrder(address account,uint64 nonce,LimitOrder action)LimitOrder(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint128 cloid)
Typehash: 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd. Підписант: API-гаманець. Дія: версія 1, id 1.
asset: індекс активу Hyperliquid.GET /v1/tee-perp/marketsперелічує ринки перпів, які приймає Hypercall, та їхні індекси.isBuy:trueдля купівлі,falseдля продажу.limitPx,sz: ціна та розмір, помножені на1e8.reduceOnly:true, якщо ордер може лише зменшувати позицію.encodedTif: ALO =1, GTC =2, IOC =3. Будь-яке інше значення відхиляється.cloid: клієнтський ID ордера, ненульовий. Згодом ви використовуєте його для скасування за cloid.
Приклад (ethers.js):
const domain = {
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
};
const types = {
LimitOrder: [
{ name: "asset", type: "uint32" },
{ name: "isBuy", type: "bool" },
{ name: "limitPx", type: "uint64" },
{ name: "sz", type: "uint64" },
{ name: "reduceOnly", type: "bool" },
{ name: "encodedTif", type: "uint8" },
{ name: "cloid", type: "uint128" }
],
HLOrder: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "LimitOrder" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: {
asset: 0,
isBuy: true,
limitPx: 5000000000000n,
sz: 100000n,
reduceOnly: false,
encodedTif: 2,
cloid: selectedNonce
}
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| Хеш структури дії | 0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41 |
| Хеш структури директиви | 0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703 |
| Дайджест для підпису | 0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5 |
Тестовий вектор використовує isBuy: true, limitPx: 5000000000000, sz: 100000, reduceOnly: false, encodedTif: 2, asset: 0 і cloid, що дорівнює nonce.
Надсилання: POST /v1/tee-perp/orders/submit з account, nonce, action і signature. Hypercall виконує перевірку маржі, після чого захищений анклав підписує й надсилає нативний ордер Hyperliquid із прикріпленим builder-кодом Hypercall. Менеджер Account має спочатку схвалити цього builder через Account.approveZeroFeeBuilder; див. Онбординг. Повний процес описано в розділі Перпи.
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 1760000000000,
"action": {
"asset": 0,
"isBuy": true,
"limitPx": "5000000000000",
"sz": "100000",
"reduceOnly": false,
"encodedTif": 2,
"cloid": "1760000000000"
},
"signature": "0x<65 byte signature>"
}
Те саме підписане повідомлення також приймається на POST /v1/actions/hl_limit_order, який кодує його як директиву в ланцюгу, що виконується через Exchange.executeUserDirective і Account.performCoreAction.
HLCancel
Скасовує один ордер за ID ордера Hyperliquid. Обгортка: HLCancel, внутрішня структура: CancelOrderByOid.
struct CancelOrderByOid {
uint32 asset;
uint64 oid; // Order ID assigned by HyperCore
}
struct HLCancel {
address account;
uint64 nonce;
CancelOrderByOid action;
}
HLCancel(address account,uint64 nonce,CancelOrderByOid action)CancelOrderByOid(uint32 asset,uint64 oid)
Typehash: 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85. Підписант: API-гаманець. Дія: версія 1, id 10. Надсилання: POST /v1/tee-perp/cancels/submit-by-oid або POST /v1/actions/hl_cancel_by_oid.
const types = {
CancelOrderByOid: [
{ name: "asset", type: "uint32" },
{ name: "oid", type: "uint64" }
],
HLCancel: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "CancelOrderByOid" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: { asset: 0, oid: 123456789n }
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 |
| Хеш структури дії | 0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727 |
| Хеш структури директиви | 0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097 |
| Дайджест для підпису | 0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330 |
Тестовий вектор використовує asset: 0 і oid: 123456789.
HLCancelByCloid
Скасовує один ордер за клієнтським ID ордера, який ви встановили в HLOrder.
struct CancelOrderByCloid {
uint32 asset;
uint128 cloid; // Client order ID
}
struct HLCancelByCloid {
address account;
uint64 nonce;
CancelOrderByCloid action;
}
HLCancelByCloid(address account,uint64 nonce,CancelOrderByCloid action)CancelOrderByCloid(uint32 asset,uint128 cloid)
Typehash: 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5. Підписант: API-гаманець. Дія: версія 1, id 11. Надсилання: POST /v1/tee-perp/cancels/submit або POST /v1/actions/hl_cancel_by_cloid.
const types = {
CancelOrderByCloid: [
{ name: "asset", type: "uint32" },
{ name: "cloid", type: "uint128" }
],
HLCancelByCloid: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "CancelOrderByCloid" }
]
};
const message = {
account: managedAccount,
nonce: selectedNonce,
action: { asset: 0, cloid: 1760000000000n }
};
const signature = await apiWalletSigner.signTypedData(domain, types, message);
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 |
| Хеш структури дії | 0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0 |
| Хеш структури директиви | 0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d |
| Дайджест для підпису | 0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d |
Тестовий вектор використовує asset: 0 і cloid: 1760000000000.
Повідомлення для перпів лише через TEE
Ці чотири повідомлення перевіряє API Hypercall, а не контракт Account, оскільки анклав виконує їх нативно на Hyperliquid і директиви в ланцюгу для них не існує. Вони використовують той самий домен HypercallApiSign і ту саму авторизацію API-гаманця, що й HLOrder (підписант має бути активним API-гаманцем Account, а Account має працювати в режимі портфельної маржі). Їхніх typehash немає в контрактах. Nonce є Unix-часом у мілісекундах.
PerpOrderTerms
HCPerpTriggerOrder і HCPerpOrderBatch обидва містять цю структуру. Лімітний дочірній ордер підписує свій байт TIF з triggerPx = 0, isMarket = false, tpsl = 0. Тригерний дочірній ордер підписує encodedTif = 0, додатний triggerPx і tpsl зі значенням 1 (тейк-профіт) або 2 (стоп-лос).
struct PerpOrderTerms {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint64 triggerPx;
bool isMarket;
uint8 tpsl;
uint128 cloid;
}
HCPerpTriggerOrder
Один ордер стоп-лос або тейк-профіт, що надсилається на POST /v1/tee-perp/orders/submit-trigger. action.orderType у запиті має бути тригерним.
struct HCPerpTriggerOrder {
address account;
uint64 nonce;
PerpOrderTerms order;
}
HCPerpTriggerOrder(address account,uint64 nonce,PerpOrderTerms action)PerpOrderTerms(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint64 triggerPx,bool isMarket,uint8 tpsl,uint128 cloid)
Typehash: 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c |
| Хеш структури дії | 0x285b3186be219b92d7159419288c0dce9bc4ad7bfc9536e009ebf24bd67f434c |
| Хеш структури директиви | 0xaa03e40b34b15e7e932ae827921930e7538387b596ef1040dbcc791e69021299 |
| Дайджест для підпису | 0xc46aadc390b66c235af15e199e188ab23fb7f7f1b9237f6c2849c264c28d94da |
Тестовий вектор є ринковим стоп-лосом на продаж у режимі reduce-only: asset: 0, isBuy: false, limitPx: 4800000000000 (найгірша ціна), sz: 100000, reduceOnly: true, encodedTif: 0, triggerPx: 4900000000000, isMarket: true, tpsl: 2, cloid: 1760000000001.
HCPerpOrderBatch
До 100 ордерів в одному групуванні, що надсилаються на POST /v1/tee-perp/orders/submit-batch. Кожен ордер має використовувати окремий cloid. grouping дорівнює 0 (без групування), 1 (normalTpsl) або 2 (positionTpsl). Пакет зараховується як одне розміщення ордера щодо ліміту запитів.
struct HCPerpOrderBatch {
address account;
uint64 nonce;
uint8 grouping;
PerpOrderTerms[] orders;
}
HCPerpOrderBatch(address account,uint64 nonce,uint8 grouping,PerpOrderTerms[] orders)PerpOrderTerms(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint64 triggerPx,bool isMarket,uint8 tpsl,uint128 cloid)
Typehash: 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b. Масив orders кодується як keccak256 від конкатенації хешів структур PerpOrderTerms у порядку надсилання.
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b |
| Хеш масиву ордерів | 0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98 |
| Хеш структури директиви | 0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0 |
| Дайджест для підпису | 0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07 |
Тестовий вектор має grouping: 1 і два ордери: лімітну купівлю GTC (limitPx: 5000000000000, sz: 100000, cloid: 1760000000000), а за нею стоп-лос із прикладу тригерного ордера.
HCPerpLeverageChange
Встановлює кредитне плече для одного активу, надсилається на POST /v1/tee-perp/leverage/submit. leverage має бути більшим за нуль.
struct PerpLeverageChange {
uint32 asset;
bool isCross;
uint32 leverage;
}
struct HCPerpLeverageChange {
address account;
uint64 nonce;
PerpLeverageChange action;
}
HCPerpLeverageChange(address account,uint64 nonce,PerpLeverageChange action)PerpLeverageChange(uint32 asset,bool isCross,uint32 leverage)
Typehash: 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463 |
| Хеш структури дії | 0x0e6e271dd56192d7fb1f37ea2eaffecfbbe2d1f79cac78dce6a6930bb8cc253e |
| Хеш структури директиви | 0xe04b169bbb0e20042308e5aad1036ce60eda75f484a4d6093dc60f2c2231129e |
| Дайджест для підпису | 0xb2a43487152a7cecc73d2b6b84d817a58dd02c559b05289a8d8e1b5c3d25e266 |
Тестовий вектор встановлює крос-плече 5x для asset: 0.
HCPerpScheduleCancel
Перемикач «мертвої руки» Hyperliquid: скасувати всі відкриті ордери в момент time (Unix-мілісекунди, щонайменше на сім секунд у майбутньому). Надсилається на POST /v1/tee-perp/schedule-cancel/submit. Щоб прибрати заплановане скасування, не вказуйте time у запиті й підпишіть time = 0. Явне надсилання 0 відхиляється.
struct PerpScheduleCancel {
uint64 time;
}
struct HCPerpScheduleCancel {
address account;
uint64 nonce;
PerpScheduleCancel action;
}
HCPerpScheduleCancel(address account,uint64 nonce,PerpScheduleCancel action)PerpScheduleCancel(uint64 time)
Typehash: 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb |
| Хеш структури дії | 0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc |
| Хеш структури директиви | 0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b |
| Дайджест для підпису | 0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc |
Тестовий вектор планує скасування на time: 1760000060000.
Підготовлене скасування з підписом менеджера
POST /v1/tee-perp/cancels/submit-prepared є шляхом скасування з підписом менеджера. Він не використовує структуру типізованих даних. Менеджер підписує дайджест підготовленого нативного скасування Hyperliquid, переданого як preparedRequest (base64), з managerSignature у канонічній low-s формі, а також authenticationSignature з часовою міткою, що автентифікує гаманець менеджера. Схему запиту див. у Довіднику API.
Директиви менеджера (HypercallManagerSign)
Підписуються менеджером Account. Використовуйте chain ID 999, name HypercallManagerSign. Account вимагає signer == manager. Надсилайте через POST /v1/actions/{action}.
HCUpdateApiWallet
Додає, замінює або видаляє (addr = 0x0) API-гаманець, збережений в Account під назвою name.
struct UpdateApiWallet {
bytes32 name; // Wallet label, ASCII left-aligned and zero padded
address addr; // API wallet address, zero to remove
}
struct HCUpdateApiWallet {
address account;
uint64 nonce;
UpdateApiWallet action;
}
HCUpdateApiWallet(address account,uint64 nonce,UpdateApiWallet action)UpdateApiWallet(bytes32 name,address addr)
Typehash: 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257. Дія: версія 0, id 2. Надсилання: POST /v1/actions/hc_update_api_wallet з action у вигляді { "name": "0x...", "addr": "0x..." }.
const domain = {
name: "HypercallManagerSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
};
const types = {
UpdateApiWallet: [
{ name: "name", type: "bytes32" },
{ name: "addr", type: "address" }
],
HCUpdateApiWallet: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "UpdateApiWallet" }
]
};
const message = {
account: accountAddress,
nonce: selectedNonce,
action: {
name: ethers.encodeBytes32String("trading-bot"),
addr: apiWalletAddress
}
};
const signature = await managerSigner.signTypedData(domain, types, message);
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257 |
| Хеш структури дії | 0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7 |
| Хеш структури директиви | 0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5 |
| Дайджест для підпису | 0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8 |
Тестовий вектор використовує name trading-bot (0x74726164696e672d626f74, доповнене нулями праворуч) і addr 0x2222222222222222222222222222222222222222. Повний процес роботи з API-гаманцем описано в розділі Онбординг. Account генерує ApiWalletUpdated(name, addr).
HLAddApiWallet
Схвалює API-гаманець Hyperliquid для Account на HyperCore.
struct AddApiWallet {
address apiWalletAddress;
string apiWalletName; // An empty name replaces the main API wallet
}
struct HLAddApiWallet {
address account;
uint64 nonce;
AddApiWallet action;
}
HLAddApiWallet(address account,uint64 nonce,AddApiWallet action)AddApiWallet(address apiWalletAddress,string apiWalletName)
Typehash: 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2. Дія: версія 1, id 9. Надсилання: POST /v1/actions/hl_add_api_wallet.
apiWalletName має тип string, тож його поле в структурі дорівнює keccak256(bytes(apiWalletName)). Ethers і viem роблять це за вас.
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2 |
| Хеш структури дії | 0xed32a441b0ee59c0252f5dff3411766289c9c35c19e3152b0b2b204176c2c7cd |
| Хеш структури директиви | 0xb990a3dfb4e8d96243539f8758b3a55249b217542bb4112f4f88ed67ec516ed9 |
| Дайджест для підпису | 0x584886d020316085de0e0dec16331b8e990558be3e8fd004c47200abbebed518 |
Тестовий вектор використовує apiWalletAddress 0x2222222222222222222222222222222222222222 і apiWalletName hl-bot.
HLSendAsset
Надсилає активи з Account на HyperCore до одержувача.
struct SendAsset {
address destination; // Recipient
address subAccount; // Recipient sub-account, zero for main
uint32 srcDex; // Source dex: 0 = perps, 4294967295 = spot
uint32 dstDex; // Destination dex: 0 = perps, 4294967295 = spot
uint64 token; // HyperCore token index (0 = USDC)
uint64 amountWei; // Amount in HyperCore wei (USDC: 1e8 per dollar)
}
struct HLSendAsset {
address account;
uint64 nonce;
SendAsset action;
}
HLSendAsset(address account,uint64 nonce,SendAsset action)SendAsset(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
Typehash: 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595. Дія: версія 1, id 13. Надсилання: POST /v1/actions/hl_send_asset.
const types = {
SendAsset: [
{ name: "destination", type: "address" },
{ name: "subAccount", type: "address" },
{ name: "srcDex", type: "uint32" },
{ name: "dstDex", type: "uint32" },
{ name: "token", type: "uint64" },
{ name: "amountWei", type: "uint64" }
],
HLSendAsset: [
{ name: "account", type: "address" },
{ name: "nonce", type: "uint64" },
{ name: "action", type: "SendAsset" }
]
};
const message = {
account: accountAddress,
nonce: selectedNonce,
action: {
destination: recipientAddress,
subAccount: ethers.ZeroAddress,
srcDex: 0,
dstDex: 0xFFFFFFFF, // spot
token: 0, // USDC
amountWei: 500000000n // 5 USDC
}
};
const signature = await managerSigner.signTypedData(domain, types, message);
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 |
| Хеш структури дії | 0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656 |
| Хеш структури директиви | 0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08 |
| Дайджест для підпису | 0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10 |
Тестовий вектор надсилає 5 USDC (amountWei: 500000000) з перпів (srcDex: 0) на спот (dstDex: 4294967295), де destination є продакшн-контрактом Exchange 0xE6b7FaA216cabb2b38B392f577C9c826378b2240.
HLSetAbstraction
Встановлює режим акаунта HyperCore для Account. Account приймає лише user, що дорівнює йому самому, і abstraction = 2 (unified-акаунт); усе інше призводить до revert. Цього вимагає портфельна маржа.
struct SetAbstraction {
address user; // Must equal the Account
uint8 abstraction; // Must be 2 (unified account)
}
struct HLSetAbstraction {
address account;
uint64 nonce;
SetAbstraction action;
}
HLSetAbstraction(address account,uint64 nonce,SetAbstraction action)SetAbstraction(address user,uint8 abstraction)
Typehash: 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786. Дія: версія 1, id 16. Надсилання: POST /v1/actions/hl_set_abstraction.
Тестовий вектор (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786 |
| Хеш структури дії | 0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e |
| Хеш структури директиви | 0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d |
| Дайджест для підпису | 0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d |
Тестовий вектор встановлює user рівним Account, а abstraction рівним 2.
HCTransferOption (зарезервовано)
Контракти визначають HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei) (typehash 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819, версія дії 0, id 1), але жоден тип підписанта йому не призначено. Account виконує revert з Account__UserDirectiveNotSupported, а API відхиляє hc_transfer_option. Не підписуйте його. Натомість переміщуйте опціонні токени через depositOption і виведення.
Транзакції менеджера без підпису
Деякі дії менеджера є прямими викликами Account, а не повідомленнями EIP-712: Account.approveZeroFeeBuilder(builder) схвалює builder Hyperliquid з максимальною комісією 0% і є обов'язковим один раз перед першим ордером на перп (див. Онбординг). Account.transferTo(recipient, token, amount) переміщує токени з Account на HyperEVM. Обидва вимагають msg.sender == manager і виконують revert, поки Account перебуває в ліквідації.
Директиви RSM (HypercallRsmSign)
Підписуються підписантом RSM і надсилаються секвенсером. Вони зараховують депозити, обробляють виведення, починають і зупиняють ліквідацію та розміщують відновлювальні ордери IOC у режимі reduce-only. Маркетмейкери й користувачі їх не підписують і не надсилають; вони задокументовані, щоб ви могли перевірити, що протокол може зробити з Account. Використовуйте chain ID 999, name HypercallRsmSign. Exchange перевіряє signer == rsmSigner (наразі 0x502E7fAbF34E84EeB115C34FE947b79A94dF886E в основній мережі), а викликач повинен мати SEQUENCER_ROLE.
Ордери та перекази RSM (виконує Account)
Вони повторно використовують структури HL у домені RSM, тож typehash збігаються з typehash для API та менеджера, а відрізняється лише роздільник домену. Account застосовує додаткові обмеження й виконує їх навіть під час ліквідації.
| Повідомлення | Typehash | Обмеження, яке застосовує Account |
|---|---|---|
HLOrder | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd | encodedTif має бути IOC (3), а ордер має бути reduceOnly або спотовим продажем за USDC (ID спотових активів від 10000 до 99999) з лімітом не більш ніж на 5% нижче спотової ціни HyperCore |
HLCancel | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 | Немає |
HLCancelByCloid | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 | Немає |
HLSendAsset | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 | destination має бути Exchange |
Тестовий вектор RSM HLOrder (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| Хеш структури дії | 0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db |
| Хеш структури директиви | 0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3 |
| Дайджест для підпису | 0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469 |
Вектор RSM HLOrder є продажем IOC у режимі reduce-only (isBuy: false, limitPx: 4800000000000, sz: 100000, reduceOnly: true, encodedTif: 3, cloid, що дорівнює nonce). Exchange.executeRsmDirective перевіряє підпис і передає дію до Account.
Системні дії (виконує Exchange)
Версія 255. Кожна обгортка має вигляд System<Action>(address account,uint64 nonce,<Action> action)<Action>(...).
| Обгортка | Внутрішній тип | Typehash |
|---|---|---|
SystemCreditToken | CreditToken(uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei) | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
SystemCreditOption | CreditOption(bytes32 underlying,uint256 expiry,uint256 strike,bool isCall,uint256 amountWei) | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
SystemStartLiquidation | StartLiquidation(int256 equity,uint256 marginNeeded) | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
SystemStopLiquidation | StopLiquidation(uint256 startTime) | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
SystemWithdrawToken | WithdrawToken(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei) | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
Повні зовнішні рядки типів:
SystemCreditToken(address account,uint64 nonce,CreditToken action)CreditToken(uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
SystemCreditOption(address account,uint64 nonce,CreditOption action)CreditOption(bytes32 underlying,uint256 expiry,uint256 strike,bool isCall,uint256 amountWei)
SystemStartLiquidation(address account,uint64 nonce,StartLiquidation action)StartLiquidation(int256 equity,uint256 marginNeeded)
SystemStopLiquidation(address account,uint64 nonce,StopLiquidation action)StopLiquidation(uint256 startTime)
SystemWithdrawToken(address account,uint64 nonce,WithdrawToken action)WithdrawToken(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)
- SystemCreditToken зараховує спотові або перп-токени з HyperCore на Account.
amountWeiмає бути ненульовим, а Account має бути активованим на HyperCore. - SystemCreditOption мінтить опціонні токени на Account, за потреби розгортаючи пару опціонів.
underlyingє словом OpenZeppelinShortString: ASCII, вирівняний ліворуч, із довжиною в байтах в останньому байті (BTCдорівнює0x42544300...03). Неканонічні кодування призводять до revert. - SystemStartLiquidation фіксує параметри аукціону й блокує Account.
marginNeededмає бути ненульовим. - SystemStopLiquidation вимагає, щоб
startTimeдорівнював зафіксованому часу початку, і повертає Account його менеджеру. - SystemWithdrawToken ставить у чергу доставку Standard USDC на HyperCore з власного балансу Exchange. Він вимагає
subAccount = 0,srcDex = 0,dstDexзі значенням0або4294967295,token = 0(USDC) іamountWei, кратного одиниці EVM. Сама лише квитанція HyperEVM не є доказом доставки на HyperCore.
Тестовий вектор SystemCreditToken (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
| Хеш структури дії | 0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011 |
| Хеш структури директиви | 0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1 |
| Дайджест для підпису | 0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254 |
Вектор зараховує 5 USDC (srcDex і dstDex зі значенням 4294967295, token: 0, amountWei: 500000000).
Тестовий вектор SystemCreditOption (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
| Хеш структури дії | 0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6 |
| Хеш структури директиви | 0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554 |
| Дайджест для підпису | 0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2 |
Вектор зараховує один колл на BTC (underlying: 0x42544300...03, expiry: 1761811200, strike: 80000, isCall: true, amountWei: 1000000000000000000).
Тестовий вектор SystemStartLiquidation (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
| Хеш структури дії | 0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803 |
| Хеш структури директиви | 0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5 |
| Дайджест для підпису | 0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b |
Вектор використовує equity: -1500000000 і marginNeeded: 20000000000 (обидва в USDC із шістьма десятковими знаками).
Тестовий вектор SystemStopLiquidation (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
| Хеш структури дії | 0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b |
| Хеш структури директиви | 0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40 |
| Дайджест для підпису | 0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af |
Вектор використовує startTime: 1760000000.
Тестовий вектор SystemWithdrawToken (акаунт 0x1111111111111111111111111111111111111111, nonce 1760000000000, ланцюг 999):
| Крок | Значення |
|---|---|
| Typehash | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
| Хеш структури дії | 0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076 |
| Хеш структури директиви | 0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2 |
| Дайджест для підпису | 0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c |
Вектор виводить 5 USDC (amountWei: 500000000) на destination 0x1111111111111111111111111111111111111111 з srcDex: 0, dstDex: 0, token: 0.
Nonce
Кожен підписант має незалежний простір nonce, який відстежується в трьох місцях.
- Контракт Account: бітова карта для кожного підписанта.
Account.isNonceUsed(signer, nonce)повертає, чи було nonce використано. Користувацька директива виконує revert зAccount__NonceAlreadyUsedу разі повторного використання.nextNonceне існує; пропуски дозволені, а порядок у ланцюгу не має значення. - Контракт Exchange: бітова карта для підписанта RSM, яку читають через
Exchange.isNonceUsed(signer, nonce). - Рушій: зберігає 100 найбільших nonce для кожного підписанта. Новий nonce не повинен бути в цьому наборі, має перевищувати найменший збережений nonce, коли набір заповнено, і має строго перебувати в межах від двох днів до і одного дня після серверного часу в мілісекундах.
Використовуйте поточний Unix-час у мілісекундах як основу nonce й збільшуйте його для кожного підписанта. Двом запитам, підписаним тим самим гаманцем у ту саму мілісекунду, потрібні різні nonce, тож ведіть лічильник. Для маршрутів перпів TEE nonce також є часовою прив'язкою запиту, тож використовуйте там реальні часові мітки в мілісекундах, а не малі цілі числа.
function isNonceUsed(address signer, uint256 nonce) external view returns (bool);
Процес перевірки підпису
- Поза ланцюгом: підписант формує дайджест EIP-712 (
0x1901 || domainSeparator || structHash) і підписує його. - API: Hypercall відновлює підписанта, перевіряє, що це активний API-гаманець або менеджер, виконує перевірку маржі в рушії для ордерів, а потім ставить директиву в чергу. Відповідь чесно повідомляє етап, деталі відхилення та хеш транзакції.
- Секвенсер: надсилає
Exchange.executeUserDirective(directive, signature). Exchange перевіряє, що Account існує, і передає виклик доAccount.executeUserDirective. - Account: відтворює дайджест зі своєї адреси, nonce і дії, відновлює підписанта за допомогою роздільника API або менеджера для цієї дії, перевіряє авторизацію, використовує nonce, а потім виконує дію. Дії HL надходять до HyperCore CoreWriter. Дії HC оновлюють реєстр API-гаманців.
- Клієнт: опитує
GET /v1/directives/{directive_id}для отримання остаточного статусу.
Маршрути перпів TEE зупиняються після кроку API: ордер на Hyperliquid виконує анклав, а не Account.
Example (HLOrder):
1. API wallet signs HLOrder with the managed account, a unique nonce, and one LimitOrder action
2. Client posts account, nonce, action, and signature to /v1/tee-perp/orders/submit
3. Hypercall recovers the API wallet and applies portfolio-margin admission
4. The enclave signs and sends the native Hyperliquid order with the Hypercall builder code
5. Client reads the stage from the response and polls for subsequent status
Застарілі та видалені елементи
Ці елементи були в попередніх версіях цієї сторінки й більше не є частиною розгорнутої системи. Їх наведено, щоб інтеграції, побудовані на їхній основі, можна було перенести.
- Кодування Processor і ActionCaster. Контракт
Processorі кодування повідомлень ActionCaster було видалено в Exchange0.2.0(лютий 2026). Директиви Account тепер проходять черезExchange.executeUserDirectiveі CoreWriter. Розгорнутий Exchange0.6.1не має жодної зі старих точок входу. - Точки входу Exchange з власними структурами.
hlRequestOrder,hlRequestCancel,hlRequestCancelByCloid,hlActionSendAsset,hcActionWithdrawToken,hcActionWithdrawOption,rsmCommandRebalanceіrsmCommandRepayбільше не існують. Їхні заміни:
| Видалене повідомлення | Заміна |
|---|---|
HLRequestCancel (пакет HLCancel{asset,oid} плюс nonce) | HLCancel з одним CancelOrderByOid на директиву |
HLRequestCancelByCloid | HLCancelByCloid з одним CancelOrderByCloid на директиву |
HLActionSendAsset (account, nonce, destination, srcDex, dstDex, token, amountWei) | HLSendAsset із SendAsset, що додає subAccount |
HCActionWithdrawToken | SystemWithdrawToken з підписом RSM, який виконує секвенсер після схвалення виведення рушієм |
HCActionWithdrawOption | Зарахування опціонів є RSM SystemCreditOption; депозити використовують depositOption |
RsmCommandRebalance | HLOrder з підписом RSM (reduce-only IOC) |
RsmCommandRepay | HLSendAsset з підписом RSM на Exchange |
- Застарілі функції ордерів.
placeCoreOrders,cancelCoreOrdersіcancelCoreOrdersByCloidвикористовували кодування MsgPack і доменCoreSignatures("Exchange", chain ID1337). Їх видалено. nextNonce. ЛічильникаnextNonce[signer]у ланцюгу більше не існує. Залишилася лише бітова карта використаних nonce (isNonceUsed).- Роздільники основної мережі з позначкою TBD. У попередньому тексті роздільники менеджера та RSM для основної мережі були позначені як TBD. Усі три зафіксовано й наведено вище.
HCTransferOption. Визначено, але ніколи не вмикалося; див. вище.
Міркування щодо безпеки
- Ключі: зберігайте ключ менеджера на апаратному гаманці. API-гаманці підписують лише ордери та скасування; використовуйте окремі ключі для кожної системи.
- Повторне використання nonce: ніколи не використовуйте nonce повторно. Відстежуйте nonce поза ланцюгом і збільшуйте їх атомарно.
- Домен: завжди підписуйте з chain ID
999в основній мережі (998у тестнеті) і звіряйте обчислений роздільник з наведеною вище таблицею. - Перевіряйте, що підписуєте: викличте
POST /v1/actions/{action}/typed-dataі порівняйте результат із вашим енкодером перед підписом на апаратному гаманці. - Перевірка в ланцюгу є остаточною: API попередньо перевіряє підписи, але Account повторно перевіряє кожну директиву в ланцюгу. Не вважайте підтвердження від API виконанням.
- Менеджер і API-гаманець: менеджери контролюють право власності, API-гаманці та переміщення активів. API-гаманці підписують лише торгові повідомлення. Використовуйте окремі ключі.
Посилання
- Онбординг: створення Account і налаштування API-гаманця
- Огляд контрактів: розгорнуті адреси та типи директив
- Перпи: процес розміщення ордерів на перпи
- Автентифікація та підпис: підпис ордерів на опціони