EIP-712-Signierung
Diese Seite ist die Referenz auf Feldebene für jede EIP-712-Nachricht, die Hypercall verifiziert: die drei Signierdomänen für Direktiven (API-Wallet, Manager, RSM), die rein Off-Chain verarbeiteten Perp-Nachrichten, die die API-Wallet-Domäne mitnutzen, sowie die eigenständige Domäne Physical Covered Call Quote. Options-Orders über die REST-API verwenden eine andere Domäne, Hypercall; siehe Authentifizierung & Signierung.
Alle Angaben hier wurden gegen die auf dem HyperEVM-Mainnet (Chain-ID 999) deployten Contracts geprüft: Exchange 0.6.1 unter 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 und Account 0.2.4. Die unten aufgeführten Domain-Separatoren und Typehashes sind in diesem deployten Bytecode eingebettet.
Überblick
Eine Direktive ist eine einzelne Aktion gegen einen Account, die Off-Chain signiert und vom Sequencer von Hypercall über Exchange.executeUserDirective oder Exchange.executeRsmDirective On-Chain eingereicht wird. Der Account stellt den Signierer aus dem EIP-712-Digest wieder her und prüft die Autorisierung:
- API-Wallet: eine Adresse, die mit
hc_update_api_walletauf dem Account registriert wurde (Account.isApiWalletActive). Signiert Orders und Stornierungen. - Manager: der Eigentümer des Accounts (
Account.manager). Signiert Änderungen an API-Wallets, Asset-Überweisungen und Änderungen des Account-Modus. - RSM-Signierer: protokollkontrolliert (
Exchange.rsmSigner). Signiert Gutschriften, Auszahlungen, Liquidationsdirektiven und Reduce-only-Recovery-Orders. Nutzer signieren diese niemals.
Kodierung von Direktiven
On-Chain ist eine Direktive abi.encodePacked(account, nonce, version, id, data):
| Bytes | Feld | Bedeutung |
|---|---|---|
| 20 | account | Die Account-Adresse (address) |
| 8 | nonce | Die Nonce des Signierers (uint64) |
| 1 | version | Aktionsfamilie |
| 3 | id | Aktions-ID innerhalb der Familie |
| Rest | data | abi.encode des inneren Aktions-Structs |
| Version | Familie | Aktions-IDs |
|---|---|---|
0 | HyperCall (HC) | 2 API-Wallet aktualisieren. 1 (Option übertragen) ist reserviert und wird abgelehnt. |
1 | HyperLiquid (HL) | 1 Limit-Order, 9 API-Wallet hinzufügen, 10 Stornierung per oid, 11 Stornierung per cloid, 13 Asset senden, 16 Abstraktion setzen |
255 | System | 1 Token gutschreiben, 2 Option gutschreiben, 3 Liquidation starten, 4 Liquidation beenden, 5 Token auszahlen |
Sie erstellen diesen Byte-String nicht selbst. Signieren Sie die typisierten Daten und reichen Sie anschließend account, nonce, action und signature bei der API ein, die die Direktive kodiert.
Struktur der typisierten Daten
Jede Direktive hat dieselbe äußere Struktur: die Account-Adresse, die Nonce des Signierers und ein inneres Aktions-Struct.
<Outer>(address account,uint64 nonce,<Inner> action)<Inner>(...)
Der äußere Typ-String hängt die innere Typdefinition an, sodass der Typehash beide abdeckt. In EIP-712-Begriffen ist primaryType der äußere Name, types enthält beide Einträge und message ist { account, nonce, action }. Die Feldreihenfolge ist Teil des Typ-Strings und muss exakt übereinstimmen.
Unsignierte Funding-Einstiegspunkte
Nicht jeder Funding-Aufruf ist eine EIP-712-Aktion. Diese Methoden sind direkte Transaktionen, die von der zahlenden Wallet oder dem Router gesendet werden:
function depositUsdcFor(address account, uint256 amount) external;
function depositOption(address account, address token, uint256 amount) external;
depositUsdcFor ist bewusst unsigniert, da msg.sender lediglich der USDC-Zahler ist. Der gutgeschriebene Hypercall-Account ist das explizite Argument account und das Event-Feld UsdcDeposit.account. Router und Zaps können diese Methode aufrufen, daher dürfen Indexer und Backend-Dienste msg.sender nicht für die Zuordnung von Gutschriften verwenden.
depositOption verbrennt Options-Token von msg.sender und emittiert Deposit(account, msg.sender, token, amount) für den RSM-Indexer. Der Gutschriftpfad für Optionen ist eventgesteuert und verwendet keine Manager-, Agent- oder RSM-Signatur des Einzahlers.
Eigenständige Domäne: Physical Covered Call Quotes
Physische Covered-Call-Quotes werden von der auf der gewählten Chain deployten Factory verifiziert. Sie verwenden weder den Exchange-Verifier noch dessen Nulladress-Domäne.
Domäne:
{
"name": "Hypercall Physical Covered Call",
"version": "1",
"chainId": "<selected chain id>",
"verifyingContract": "<exact PhysicalCoveredCallFactory address>"
}
Signierer: der in PhysicalCoveredCallQuote.marketMaker kodierte Market Maker.
Kanonische verschachtelte Typen:
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)
Die Factory berechnet requestHash aus dem vollständigen verschachtelten Request neu, bevor sie den Signierer des Quotes wiederherstellt. Die Signatur bindet daher den Verkäufer, den Basiswert-Wrapper, die Anzahl der Wrapper-Anteile, den Strike, den Verfall, die Prämie, die Quote-Deadline, die Nonce, die Chain-ID und die Factory-Adresse. Settlement-Token und Dezimalstellen sind maßgebliche Factory-Konfiguration und keine separat signierten Werte. Pyth ist in dieser orakellosen Generation nicht vorhanden. Sowohl der Quote-Digest als auch die Maker-Nonce werden verbraucht, wenn der Verkäufer einen Vault finanziert.
Nur der im Request kodierte Verkäufer kann den signierten Quote einreichen. Das Funding mintet das Writer-Claim-NFT an den Verkäufer und das Long-Options-NFT an den quotierenden Market Maker, sofern dieser Maker ein zulässiger Empfänger ist, während die optionale Käufer-Allowlist aktiviert ist. Eine gültige Signatur autorisiert das Funding, nicht die Ausübung.
Nur der aktuelle Eigentümer des Long-Options-NFTs darf die Ausübung aufrufen. Diese Owner-only-Regel verhindert, dass ein ERC-721-Operator das Settlement-Token-Allowance des Eigentümers verbraucht. Ein genehmigter Operator darf das NFT weiterhin nach den Standard-ERC-721-Regeln übertragen, wodurch das wirtschaftliche Recht an einen zulässigen Empfänger übergeht, solange das Käufer-Gate aktiviert ist. Eine erfolgreiche Ausübung zieht den Strike-Betrag vom aufrufenden Eigentümer ein, liefert den Basiswert an diesen Eigentümer und verbrennt das Long-Options-NFT.
EIP-712-Domain-Separatoren
Die drei Direktiven-Domänen verwenden dieselbe Struktur und unterscheiden sich nur in name. Der verifyingContract ist die Nulladresse, daher ist dieselbe Signatur für jeden Account auf der Chain gültig, und erst die Account-Adresse innerhalb der Nachricht bindet sie an einen Account.
{
"name": "<DomainName>",
"version": "1",
"chainId": <chainId>,
"verifyingContract": "0x0000000000000000000000000000000000000000"
}
Der Domänentyp ist EIP712Domain(string name,string version,uint256 chainId,address verifyingContract).
Chain-IDs: Mainnet 999, Testnet 998. Der Account wählt den Separator anhand der Chain, auf der er läuft, sodass eine Testnet-Signatur niemals auf dem Mainnet verifiziert wird.
| Domäne | name | version | Signierer | Chain | Separator |
|---|---|---|---|---|---|
| API-Wallet | HypercallApiSign | 1 | API-Wallet | 999 | 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb |
| API-Wallet | HypercallApiSign | 1 | API-Wallet | 998 | 0x339bee4c00da9a5361f687797205c8d03f323659f5d9dc9e0505b9437ddee25e |
| Manager | HypercallManagerSign | 1 | Manager | 999 | 0xc9b5b0b8b0d9d7ba716326acbf795cfe431ef960a25a8f958d6569bea2f1516e |
| Manager | HypercallManagerSign | 1 | Manager | 998 | 0xd1f76b6138be892c14b71b0569bdb049cb44f239d34c78ef1ffaacd2466f9f18 |
| RSM | HypercallRsmSign | 1 | RSM-Signierer | 999 | 0x3d0cae2af623c614099dbadd67a1e1457fabde576aa270a70a57e39bf338a7be |
| RSM | HypercallRsmSign | 1 | RSM-Signierer | 998 | 0x650b282053fb61d3fd477bdc28f6434311fe905e27cc4ca643e87e802c45938c |
Berechnen Sie den Separator selbst und vergleichen Sie ihn, bevor Sie irgendetwas signieren:
import { ethers } from "ethers";
const separator = ethers.TypedDataEncoder.hashDomain({
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
});
// 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb
Nachrichtenreferenz
Matrix der Signierer und Endpunkte
| Nachricht | Domäne | Signierer | Einreichen bei | Führt aus |
|---|---|---|---|---|
HLOrder | API | API-Wallet | POST /v1/tee-perp/orders/submit oder POST /v1/actions/hl_limit_order | Hyperliquid-Limit-Order |
HLCancel | API | API-Wallet | POST /v1/tee-perp/cancels/submit-by-oid oder POST /v1/actions/hl_cancel_by_oid | Stornierung per oid |
HLCancelByCloid | API | API-Wallet | POST /v1/tee-perp/cancels/submit oder POST /v1/actions/hl_cancel_by_cloid | Stornierung per cloid |
HCPerpTriggerOrder | API | API-Wallet | POST /v1/tee-perp/orders/submit-trigger | Native Trigger-Order (nur TEE) |
HCPerpOrderBatch | API | API-Wallet | POST /v1/tee-perp/orders/submit-batch | Nativer Order-Batch (nur TEE) |
HCPerpLeverageChange | API | API-Wallet | POST /v1/tee-perp/leverage/submit | Hebel-Änderung (nur TEE) |
HCPerpScheduleCancel | API | API-Wallet | POST /v1/tee-perp/schedule-cancel/submit | Totmannschalter (nur TEE) |
HCUpdateApiWallet | Manager | Manager | POST /v1/actions/hc_update_api_wallet | API-Wallet-Register des Account |
HLAddApiWallet | Manager | Manager | POST /v1/actions/hl_add_api_wallet | API-Wallet-Genehmigung auf HyperCore |
HLSendAsset | Manager | Manager | POST /v1/actions/hl_send_asset | HyperCore-sendAsset vom Account |
HLSetAbstraction | Manager | Manager | POST /v1/actions/hl_set_abstraction | HyperCore-Account-Modus (nur Unified) |
HCTransferOption | Manager | Manager | Nicht akzeptiert | Reserviert, wird On-Chain abgelehnt |
HLOrder, HLCancel, HLCancelByCloid, HLSendAsset | RSM | RSM-Signierer | Nur Sequencer | Recovery-Orders und Sweeps über den Account |
System* | RSM | RSM-Signierer | Nur Sequencer | Gutschriften, Auszahlungen, Liquidation über die Exchange |
Alle Routen /v1/actions/{action} erwarten account, nonce, action und signature. POST /v1/actions/{action}/typed-data gibt die exakten zu signierenden typisierten Daten für diesen Request zurück und ist der einfachste Weg, Ihren Encoder zu überprüfen. GET /v1/directives/{directive_id} meldet das On-Chain-Ergebnis. Request-Schemas finden Sie in der API-Referenz.
Wire-Konventionen
nonceund jedes Feld vom Typuint64,uint128oderuint256sind JSON-Ganzzahlen bis9007199254740991oder Dezimal-Strings. Verwenden Sie oberhalb dieses Werts Strings.signatureist ein 65-Byte-Hex-String mit0x-Präfix (r || s || v).vdarf0,1,27oder28sein.bytes32-Felder sind 32-Byte-Hex mit0x-Präfix. Adressen sind Hex mit Checksumme oder in Kleinbuchstaben.- Perp-Preise und -Größen sind die HyperCore-Ganzzahlen mit
1e8, zum Beispiel ist$50,000gleich5000000000000und0.001Coins sind100000.
API-Wallet-Direktiven (HypercallApiSign)
Signiert von einer aktiven API-Wallet des Accounts. Verwenden Sie Chain-ID 999 und name HypercallApiSign.
Die Testvektoren verwenden einen Platzhalter-Account und eine feste Nonce, damit Sie Ihren Encoder Byte für Byte prüfen können. Der Digest ist keccak256(0x1901 || domainSeparator || directiveStructHash).
HLOrder
Eine Hyperliquid-Limit-Order für den Account.
Struct:
struct LimitOrder {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint128 cloid;
}
struct HLOrder {
address account;
uint64 nonce;
LimitOrder action;
}
Kanonischer EIP-712-Typ:
HLOrder(address account,uint64 nonce,LimitOrder action)LimitOrder(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint128 cloid)
Typehash: 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd. Signierer: API-Wallet. Aktion: Version 1, ID 1.
asset: der Hyperliquid-Asset-Index.GET /v1/tee-perp/marketslistet die von Hypercall akzeptierten Perp-Märkte und ihre Indizes auf.isBuy:truezum Kaufen,falsezum Verkaufen.limitPx,sz: Preis und Größe multipliziert mit1e8.reduceOnly:true, wenn die Order eine Position nur reduzieren darf.encodedTif: ALO =1, GTC =2, IOC =3. Jeder andere Wert wird abgelehnt.cloid: Client-Order-ID, ungleich null. Sie verwenden sie später für die Stornierung per cloid.
Beispiel (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);
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| Aktions-Struct-Hash | 0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41 |
| Direktiven-Struct-Hash | 0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703 |
| Zu signierender Digest | 0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5 |
Der Testvektor verwendet isBuy: true, limitPx: 5000000000000, sz: 100000, reduceOnly: false, encodedTif: 2, asset: 0 und cloid gleich der Nonce.
Einreichen: POST /v1/tee-perp/orders/submit mit account, nonce, action und signature. Hypercall führt die Margin-Prüfung durch, anschließend signiert eine sichere Enclave die native Hyperliquid-Order und sendet sie mit angehängtem Hypercall-Builder-Code. Der Manager des Accounts muss diesen Builder zuvor mit Account.approveZeroFeeBuilder genehmigen; siehe Onboarding. Den vollständigen Ablauf finden Sie unter Perps.
{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 1760000000000,
"action": {
"asset": 0,
"isBuy": true,
"limitPx": "5000000000000",
"sz": "100000",
"reduceOnly": false,
"encodedTif": 2,
"cloid": "1760000000000"
},
"signature": "0x<65 byte signature>"
}
Dieselbe signierte Nachricht wird auch unter POST /v1/actions/hl_limit_order akzeptiert, wo sie als On-Chain-Direktive kodiert und über Exchange.executeUserDirective und Account.performCoreAction ausgeführt wird.
HLCancel
Storniert eine Order anhand der Hyperliquid-Order-ID. Der Wrapper ist HLCancel, das innere Struct ist 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. Signierer: API-Wallet. Aktion: Version 1, ID 10. Einreichen: POST /v1/tee-perp/cancels/submit-by-oid oder 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);
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 |
| Aktions-Struct-Hash | 0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727 |
| Direktiven-Struct-Hash | 0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097 |
| Zu signierender Digest | 0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330 |
Der Testvektor verwendet asset: 0 und oid: 123456789.
HLCancelByCloid
Storniert eine Order anhand der Client-Order-ID, die Sie in HLOrder gesetzt haben.
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. Signierer: API-Wallet. Aktion: Version 1, ID 11. Einreichen: POST /v1/tee-perp/cancels/submit oder 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);
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 |
| Aktions-Struct-Hash | 0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0 |
| Direktiven-Struct-Hash | 0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d |
| Zu signierender Digest | 0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d |
Der Testvektor verwendet asset: 0 und cloid: 1760000000000.
Perp-Nachrichten nur für TEE
Diese vier Nachrichten werden von der Hypercall-API verifiziert, nicht vom Account-Contract, da die Enclave sie nativ auf Hyperliquid ausführt und für sie keine On-Chain-Direktive existiert. Sie verwenden dieselbe Domäne HypercallApiSign und dieselbe API-Wallet-Autorisierung wie HLOrder (der Signierer muss eine aktive API-Wallet des Accounts sein, und der Account muss Portfolio-Margin nutzen). Ihre Typehashes sind nicht in den Contracts enthalten. Nonces sind Unix-Zeit in Millisekunden.
PerpOrderTerms
HCPerpTriggerOrder und HCPerpOrderBatch betten beide dieses Struct ein. Eine Limit-Child-Order signiert ihr TIF-Byte mit triggerPx = 0, isMarket = false, tpsl = 0. Eine Trigger-Child-Order signiert encodedTif = 0, ein positives triggerPx und tpsl mit 1 (Take-Profit) oder 2 (Stop-Loss).
struct PerpOrderTerms {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint64 triggerPx;
bool isMarket;
uint8 tpsl;
uint128 cloid;
}
HCPerpTriggerOrder
Eine einzelne Stop-Loss- oder Take-Profit-Order, eingereicht bei POST /v1/tee-perp/orders/submit-trigger. Das Request-Feld action.orderType muss ein Trigger sein.
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
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c |
| Aktions-Struct-Hash | 0x285b3186be219b92d7159419288c0dce9bc4ad7bfc9536e009ebf24bd67f434c |
| Direktiven-Struct-Hash | 0xaa03e40b34b15e7e932ae827921930e7538387b596ef1040dbcc791e69021299 |
| Zu signierender Digest | 0xc46aadc390b66c235af15e199e188ab23fb7f7f1b9237f6c2849c264c28d94da |
Der Testvektor ist ein Reduce-only-Market-Stop-Loss-Verkauf: asset: 0, isBuy: false, limitPx: 4800000000000 (schlechtester Preis), sz: 100000, reduceOnly: true, encodedTif: 0, triggerPx: 4900000000000, isMarket: true, tpsl: 2, cloid: 1760000000001.
HCPerpOrderBatch
Bis zu 100 Orders unter einer Gruppierung, eingereicht bei POST /v1/tee-perp/orders/submit-batch. Jede Order muss eine eigene cloid verwenden. grouping ist 0 (keine Gruppierung), 1 (normalTpsl) oder 2 (positionTpsl). Ein Batch zählt als eine Order-Platzierung gegenüber dem Rate-Limit.
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. Das Array orders wird als keccak256 der verketteten PerpOrderTerms-Struct-Hashes in Einreichungsreihenfolge kodiert.
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b |
| Hash des Orders-Arrays | 0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98 |
| Direktiven-Struct-Hash | 0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0 |
| Zu signierender Digest | 0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07 |
Der Testvektor ist grouping: 1 mit zwei Orders: ein GTC-Limit-Kauf (limitPx: 5000000000000, sz: 100000, cloid: 1760000000000), gefolgt vom Stop-Loss aus dem Trigger-Beispiel.
HCPerpLeverageChange
Setzt den Hebel für ein Asset, eingereicht bei POST /v1/tee-perp/leverage/submit. leverage muss größer als null sein.
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
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463 |
| Aktions-Struct-Hash | 0x0e6e271dd56192d7fb1f37ea2eaffecfbbe2d1f79cac78dce6a6930bb8cc253e |
| Direktiven-Struct-Hash | 0xe04b169bbb0e20042308e5aad1036ce60eda75f484a4d6093dc60f2c2231129e |
| Zu signierender Digest | 0xb2a43487152a7cecc73d2b6b84d817a58dd02c559b05289a8d8e1b5c3d25e266 |
Der Testvektor setzt den Cross-Hebel auf 5x für asset: 0.
HCPerpScheduleCancel
Der Totmannschalter von Hyperliquid: storniert jede offene Order zum Zeitpunkt time (Unix-Millisekunden, mindestens sieben Sekunden in der Zukunft). Eingereicht bei POST /v1/tee-perp/schedule-cancel/submit. Um eine geplante Stornierung aufzuheben, lassen Sie time im Request weg und signieren time = 0. Das Senden einer expliziten 0 wird abgelehnt.
struct PerpScheduleCancel {
uint64 time;
}
struct HCPerpScheduleCancel {
address account;
uint64 nonce;
PerpScheduleCancel action;
}
HCPerpScheduleCancel(address account,uint64 nonce,PerpScheduleCancel action)PerpScheduleCancel(uint64 time)
Typehash: 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb |
| Aktions-Struct-Hash | 0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc |
| Direktiven-Struct-Hash | 0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b |
| Zu signierender Digest | 0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc |
Der Testvektor plant eine Stornierung zum Zeitpunkt time: 1760000060000.
Vom Manager signierte vorbereitete Stornierung
POST /v1/tee-perp/cancels/submit-prepared ist der vom Manager signierte Stornierungspfad. Er verwendet kein Struct für typisierte Daten. Der Manager signiert den Digest einer vorbereiteten nativen Hyperliquid-Stornierung, die als preparedRequest (Base64) mit managerSignature in kanonischer Low-s-Form übergeben wird, zusammen mit einer mit Zeitstempel versehenen authenticationSignature, die die Manager-Wallet authentifiziert. Das Request-Schema finden Sie in der API-Referenz.
Manager-Direktiven (HypercallManagerSign)
Signiert vom Manager des Accounts. Verwenden Sie Chain-ID 999 und name HypercallManagerSign. Der Account verlangt signer == manager. Einreichen mit POST /v1/actions/{action}.
HCUpdateApiWallet
Fügt die unter name im Account gespeicherte API-Wallet hinzu, ersetzt sie oder entfernt sie (addr = 0x0).
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. Aktion: Version 0, ID 2. Einreichen: POST /v1/actions/hc_update_api_wallet mit action von { "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);
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257 |
| Aktions-Struct-Hash | 0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7 |
| Direktiven-Struct-Hash | 0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5 |
| Zu signierender Digest | 0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8 |
Der Testvektor verwendet name trading-bot (0x74726164696e672d626f74, rechts mit Nullen aufgefüllt) und addr 0x2222222222222222222222222222222222222222. Den vollständigen API-Wallet-Ablauf finden Sie unter Onboarding. Der Account emittiert ApiWalletUpdated(name, addr).
HLAddApiWallet
Genehmigt eine Hyperliquid-API-Wallet für den Account auf 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. Aktion: Version 1, ID 9. Einreichen: POST /v1/actions/hl_add_api_wallet.
apiWalletName ist ein string, daher ist sein Struct-Feld keccak256(bytes(apiWalletName)). Ethers und viem erledigen dies für Sie.
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2 |
| Aktions-Struct-Hash | 0xed32a441b0ee59c0252f5dff3411766289c9c35c19e3152b0b2b204176c2c7cd |
| Direktiven-Struct-Hash | 0xb990a3dfb4e8d96243539f8758b3a55249b217542bb4112f4f88ed67ec516ed9 |
| Zu signierender Digest | 0x584886d020316085de0e0dec16331b8e990558be3e8fd004c47200abbebed518 |
Der Testvektor verwendet apiWalletAddress 0x2222222222222222222222222222222222222222 und apiWalletName hl-bot.
HLSendAsset
Sendet Assets vom Account auf HyperCore an ein Ziel.
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. Aktion: Version 1, ID 13. Einreichen: 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);
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 |
| Aktions-Struct-Hash | 0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656 |
| Direktiven-Struct-Hash | 0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08 |
| Zu signierender Digest | 0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10 |
Der Testvektor sendet 5 USDC (amountWei: 500000000) von Perps (srcDex: 0) zu Spot (dstDex: 4294967295) mit destination gleich der Produktions-Exchange 0xE6b7FaA216cabb2b38B392f577C9c826378b2240.
HLSetAbstraction
Setzt den HyperCore-Account-Modus des Accounts. Der Account akzeptiert nur user gleich sich selbst und abstraction = 2 (Unified Account); alles andere führt zu einem Revert. Portfolio-Margin setzt dies voraus.
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. Aktion: Version 1, ID 16. Einreichen: POST /v1/actions/hl_set_abstraction.
Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786 |
| Aktions-Struct-Hash | 0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e |
| Direktiven-Struct-Hash | 0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d |
| Zu signierender Digest | 0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d |
Der Testvektor setzt user auf den Account und abstraction auf 2.
HCTransferOption (reserviert)
Die Contracts definieren HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei) (Typehash 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819, Aktionsversion 0, ID 1), ihm ist jedoch kein Signierertyp zugeordnet. Der Account führt einen Revert mit Account__UserDirectiveNotSupported aus, und die API lehnt hc_transfer_option ab. Signieren Sie diese Nachricht nicht. Verschieben Sie Options-Token stattdessen mit depositOption und Auszahlungen.
Manager-Transaktionen ohne Signatur
Einige Manager-Aktionen sind direkte Account-Aufrufe und keine EIP-712-Nachrichten: Account.approveZeroFeeBuilder(builder) genehmigt einen Hyperliquid-Builder mit einer maximalen Gebühr von 0 % und ist einmalig vor der ersten Perp-Order erforderlich (siehe Onboarding). Account.transferTo(recipient, token, amount) verschiebt Token auf HyperEVM aus dem Account. Beide erfordern msg.sender == manager und führen zu einem Revert, solange sich der Account in Liquidation befindet.
RSM-Direktiven (HypercallRsmSign)
Signiert vom RSM-Signierer und eingereicht vom Sequencer. Sie schreiben Einzahlungen gut, verarbeiten Auszahlungen, starten und beenden Liquidationen und platzieren Reduce-only-IOC-Recovery-Orders. Market Maker und Nutzer signieren oder reichen sie nicht ein; sie sind dokumentiert, damit Sie nachprüfen können, was das Protokoll mit einem Account tun darf. Verwenden Sie Chain-ID 999 und name HypercallRsmSign. Die Exchange prüft signer == rsmSigner (derzeit 0x502E7fAbF34E84EeB115C34FE947b79A94dF886E auf dem Mainnet), und der Aufrufer muss SEQUENCER_ROLE besitzen.
RSM-Orders und Sweeps (vom Account ausgeführt)
Diese verwenden die HL-Structs unter der RSM-Domäne wieder, daher sind die Typehashes identisch mit denen für API und Manager, und nur der Domain-Separator unterscheidet sich. Der Account erzwingt zusätzliche Einschränkungen und führt sie auch während einer Liquidation aus.
| Nachricht | Typehash | Vom Account erzwungene Einschränkung |
|---|---|---|
HLOrder | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd | encodedTif muss IOC (3) sein, und die Order muss reduceOnly sein oder ein Spot-Verkauf gegen USDC (Spot-Asset-IDs 10000 bis 99999), limitiert auf höchstens 5 % unter dem HyperCore-Spotpreis |
HLCancel | 0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85 | Keine |
HLCancelByCloid | 0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5 | Keine |
HLSendAsset | 0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595 | destination muss die Exchange sein |
RSM-HLOrder-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd |
| Aktions-Struct-Hash | 0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db |
| Direktiven-Struct-Hash | 0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3 |
| Zu signierender Digest | 0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469 |
Der RSM-HLOrder-Vektor ist ein Reduce-only-IOC-Verkauf (isBuy: false, limitPx: 4800000000000, sz: 100000, reduceOnly: true, encodedTif: 3, cloid gleich der Nonce). Exchange.executeRsmDirective verifiziert die Signatur und leitet die Aktion an den Account weiter.
Systemaktionen (von der Exchange ausgeführt)
Version 255. Jeder Wrapper ist System<Action>(address account,uint64 nonce,<Action> action)<Action>(...).
| Wrapper | Innerer Typ | 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 |
Vollständige äußere Typ-Strings:
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 schreibt dem Account Spot- oder Perp-Token von HyperCore gut.
amountWeimuss ungleich null sein, und der Account muss auf HyperCore aktiviert sein. - SystemCreditOption mintet Options-Token an den Account und deployt bei Bedarf das Options-Paar.
underlyingist ein OpenZeppelin-ShortString-Wort: ASCII linksbündig mit der Byte-Länge im letzten Byte (BTCist0x42544300...03). Nicht-kanonische Kodierungen führen zu einem Revert. - SystemStartLiquidation zeichnet die Auktionsparameter auf und sperrt den Account.
marginNeededmuss ungleich null sein. - SystemStopLiquidation verlangt, dass
startTimedem aufgezeichneten Start entspricht, und gibt den Account an seinen Manager zurück. - SystemWithdrawToken stellt die Lieferung von Standard-USDC auf HyperCore aus dem eigenen Guthaben der Exchange in die Warteschlange. Es erfordert
subAccount = 0,srcDex = 0,dstDexmit0oder4294967295,token = 0(USDC) sowie einenamountWei, der ein ganzzahliges Vielfaches der EVM-Einheit ist. Eine HyperEVM-Quittung allein ist kein Nachweis für die Lieferung auf HyperCore.
SystemCreditToken-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052 |
| Aktions-Struct-Hash | 0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011 |
| Direktiven-Struct-Hash | 0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1 |
| Zu signierender Digest | 0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254 |
Der Vektor schreibt 5 USDC gut (srcDex und dstDex mit 4294967295, token: 0, amountWei: 500000000).
SystemCreditOption-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae |
| Aktions-Struct-Hash | 0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6 |
| Direktiven-Struct-Hash | 0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554 |
| Zu signierender Digest | 0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2 |
Der Vektor schreibt eine BTC-Call-Option gut (underlying: 0x42544300...03, expiry: 1761811200, strike: 80000, isCall: true, amountWei: 1000000000000000000).
SystemStartLiquidation-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e |
| Aktions-Struct-Hash | 0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803 |
| Direktiven-Struct-Hash | 0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5 |
| Zu signierender Digest | 0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b |
Der Vektor verwendet equity: -1500000000 und marginNeeded: 20000000000 (beide USDC mit sechs Dezimalstellen).
SystemStopLiquidation-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3 |
| Aktions-Struct-Hash | 0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b |
| Direktiven-Struct-Hash | 0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40 |
| Zu signierender Digest | 0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af |
Der Vektor verwendet startTime: 1760000000.
SystemWithdrawToken-Testvektor (Account 0x1111111111111111111111111111111111111111, Nonce 1760000000000, Chain 999):
| Schritt | Wert |
|---|---|
| Typehash | 0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883 |
| Aktions-Struct-Hash | 0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076 |
| Direktiven-Struct-Hash | 0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2 |
| Zu signierender Digest | 0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c |
Der Vektor zahlt 5 USDC (amountWei: 500000000) an destination 0x1111111111111111111111111111111111111111 aus, mit srcDex: 0, dstDex: 0, token: 0.
Nonces
Jeder Signierer hat einen unabhängigen Nonce-Raum, der an drei Stellen verfolgt wird.
- Account-Contract: eine Bitmap pro Signierer.
Account.isNonceUsed(signer, nonce)gibt zurück, ob eine Nonce verbraucht wurde. Eine Nutzer-Direktive führt bei Wiederverwendung zu einem Revert mitAccount__NonceAlreadyUsed. Es gibt keinnextNonce; Lücken sind erlaubt, und die Reihenfolge spielt On-Chain keine Rolle. - Exchange-Contract: eine Bitmap für den RSM-Signierer, abrufbar mit
Exchange.isNonceUsed(signer, nonce). - Engine: speichert die 100 höchsten Nonces pro Signierer. Eine neue Nonce darf nicht in der Menge enthalten sein, muss die kleinste gespeicherte Nonce übersteigen, sobald die Menge voll ist, und muss strikt innerhalb von zwei Tagen vor und einem Tag nach der Serverzeit in Millisekunden liegen.
Verwenden Sie die aktuelle Unix-Zeit in Millisekunden als Nonce-Ausgangswert und erhöhen Sie sie pro Signierer. Zwei Requests, die von derselben Wallet in derselben Millisekunde signiert werden, benötigen unterschiedliche Nonces, führen Sie daher einen Zähler. Bei den TEE-Perp-Routen ist die Nonce zugleich der Zeitanker des Requests, verwenden Sie dort also echte Millisekunden-Zeitstempel statt kleiner Ganzzahlen.
function isNonceUsed(address signer, uint256 nonce) external view returns (bool);
Ablauf der Signaturverifizierung
- Off-Chain: Der Signierer erstellt den EIP-712-Digest (
0x1901 || domainSeparator || structHash) und signiert ihn. - API: Hypercall stellt den Signierer wieder her, prüft, ob es sich um eine aktive API-Wallet oder den Manager handelt, führt bei Orders die Margin-Prüfung der Engine durch und stellt die Direktive anschließend in die Warteschlange. Die Antwort meldet den tatsächlichen Verarbeitungsstand, Ablehnungsdetails und den Transaktions-Hash.
- Sequencer: reicht
Exchange.executeUserDirective(directive, signature)ein. Die Exchange prüft, ob der Account existiert, und leitet anAccount.executeUserDirectiveweiter. - Account: rekonstruiert den Digest aus der eigenen Adresse, der Nonce und der Aktion, stellt den Signierer mit dem API- oder Manager-Separator für diese Aktion wieder her, prüft die Autorisierung, verbraucht die Nonce und führt dann aus. HL-Aktionen gehen an den HyperCore-CoreWriter. HC-Aktionen aktualisieren das API-Wallet-Register.
- Client: fragt
GET /v1/directives/{directive_id}nach dem finalen Status ab.
Die TEE-Perp-Routen enden nach dem API-Schritt: Die Enclave, nicht der Account, führt die Order auf Hyperliquid aus.
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
Veraltet und entfernt
Diese Bestandteile erschienen in früheren Versionen dieser Seite und sind nicht mehr Teil des deployten Systems. Sie sind aufgeführt, damit darauf aufbauende Integrationen migriert werden können.
- Processor- und ActionCaster-Kodierung. Der
Processor-Contract und die ActionCaster-Nachrichtenkodierung wurden in Exchange0.2.0(Februar 2026) entfernt. Account-Direktiven laufen jetzt überExchange.executeUserDirectiveund CoreWriter. Die deployte Exchange0.6.1enthält keinen der alten Einstiegspunkte. - Exchange-Einstiegspunkte mit eigenen Structs.
hlRequestOrder,hlRequestCancel,hlRequestCancelByCloid,hlActionSendAsset,hcActionWithdrawToken,hcActionWithdrawOption,rsmCommandRebalanceundrsmCommandRepayexistieren nicht mehr. Ihre Ersatzlösungen:
| Entfernte Nachricht | Ersatz |
|---|---|
HLRequestCancel (Batch aus HLCancel{asset,oid} plus Nonce) | HLCancel mit einem CancelOrderByOid pro Direktive |
HLRequestCancelByCloid | HLCancelByCloid mit einem CancelOrderByCloid pro Direktive |
HLActionSendAsset (account, nonce, destination, srcDex, dstDex, token, amountWei) | HLSendAsset mit SendAsset, das subAccount ergänzt |
HCActionWithdrawToken | RSM-signiertes SystemWithdrawToken, vom Sequencer ausgeführt, nachdem die Engine die Auszahlung genehmigt hat |
HCActionWithdrawOption | Options-Gutschriften sind RSM-SystemCreditOption; Einzahlungen verwenden depositOption |
RsmCommandRebalance | RSM-signiertes HLOrder (Reduce-only IOC) |
RsmCommandRepay | RSM-signiertes HLSendAsset an die Exchange |
- Legacy-Order-Funktionen.
placeCoreOrders,cancelCoreOrdersundcancelCoreOrdersByCloidverwendeten eine MsgPack-Kodierung und die DomäneCoreSignatures("Exchange", Chain-ID1337). Sie wurden entfernt. nextNonce. Der On-Chain-ZählernextNonce[signer]existiert nicht mehr. Nur die Bitmap der verwendeten Nonces (isNonceUsed) bleibt bestehen.- Als TBD markierte Mainnet-Separatoren. Frühere Fassungen führten die Mainnet-Separatoren für Manager und RSM als TBD. Alle drei sind festgelegt und oben aufgeführt.
HCTransferOption. Definiert, aber nie aktiviert; siehe oben.
Sicherheitshinweise
- Schlüssel: Bewahren Sie den Manager-Schlüssel auf einer Hardware-Wallet auf. API-Wallets signieren nur Orders und Stornierungen; verwenden Sie separate Schlüssel pro System.
- Nonce-Replay: Verwenden Sie niemals eine Nonce erneut. Verfolgen Sie Nonces Off-Chain und erhöhen Sie sie atomar.
- Domäne: Signieren Sie auf dem Mainnet immer mit Chain-ID
999(998auf dem Testnet) und prüfen Sie Ihren berechneten Separator gegen die obige Tabelle. - Prüfen Sie, was Sie signieren: Rufen Sie
POST /v1/actions/{action}/typed-dataauf und vergleichen Sie das Ergebnis mit Ihrem eigenen Encoder, bevor Sie mit einer Hardware-Wallet signieren. - Die On-Chain-Verifizierung ist maßgeblich: Die API prüft Signaturen vorab, aber der Account verifiziert jede Direktive On-Chain erneut. Werten Sie eine Bestätigung der API nicht als Ausführung.
- Manager vs. API-Wallet: Manager kontrollieren Eigentum, API-Wallets und Asset-Bewegungen. API-Wallets signieren nur Handelsnachrichten. Verwenden Sie separate Schlüssel.
Referenzen
- Onboarding zur Account-Erstellung und Einrichtung der API-Wallet
- Contracts-Überblick zu deployten Adressen und Direktiventypen
- Perps zum Ablauf von Perp-Orders
- Authentifizierung & Signierung zur Signierung von Options-Orders