Cette page a été traduite automatiquement. La version anglaise fait référence. Lire en anglais →
Aller au contenu principal

Signature EIP-712

Cette page est la référence, champ par champ, de chaque message EIP-712 vérifié par Hypercall : les trois domaines de signature des directives (portefeuille API, Manager, RSM), les messages perp uniquement hors chaîne qui partagent le domaine du portefeuille API, et le domaine autonome Physical Covered Call Quote. Les ordres d'options de l'API REST utilisent un domaine différent, Hypercall ; voir Authentification et signature.

Tout ce qui figure ici a été vérifié par rapport aux contrats déployés sur le réseau principal HyperEVM (chain ID 999) : Exchange 0.6.1 à l'adresse 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 et Account 0.2.4. Les séparateurs de domaine et les typehashes ci-dessous sont intégrés dans ce bytecode déployé.

Vue d'ensemble​

Une directive est une action unique sur un Account, signée hors chaîne et soumise on-chain par le séquenceur de Hypercall via Exchange.executeUserDirective ou Exchange.executeRsmDirective. L'Account récupère le signataire à partir du digest EIP-712 et vérifie l'autorisation :

  1. Portefeuille API : une adresse enregistrée sur l'Account avec hc_update_api_wallet (Account.isApiWalletActive). Signe les ordres et les annulations.
  2. Manager : le propriétaire de l'Account (Account.manager). Signe les modifications de portefeuille API, les envois d'actifs et les changements de mode de compte.
  3. Signataire RSM : contrôlé par le protocole (Exchange.rsmSigner). Signe les crédits, les retraits, les directives de liquidation et les ordres de récupération reduce-only. Les utilisateurs ne les signent jamais.

Encodage des directives​

On-chain, une directive est abi.encodePacked(account, nonce, version, id, data) :

OctetsChampSignification
20accountL'adresse de l'Account (address)
8nonceLe nonce du signataire (uint64)
1versionFamille d'actions
3idIdentifiant de l'action au sein de la famille
restedataabi.encode de la structure d'action interne
VersionFamilleIdentifiants d'action
0HyperCall (HC)2 mise à jour du portefeuille API. 1 (transfert d'option) est réservé et rejeté.
1HyperLiquid (HL)1 ordre limite, 9 ajout de portefeuille API, 10 annulation par oid, 11 annulation par cloid, 13 envoi d'actif, 16 définition de l'abstraction
255Système1 crédit de token, 2 crédit d'option, 3 début de liquidation, 4 fin de liquidation, 5 retrait de token

Vous ne construisez pas cette chaîne d'octets vous-même. Signez les données typées, puis soumettez account, nonce, action et signature à l'API, qui encode la directive.

Forme des données typées​

Chaque directive a la même forme externe : l'adresse de l'Account, le nonce du signataire et une structure d'action interne.

<Outer>(address account,uint64 nonce,<Inner> action)<Inner>(...)

La chaîne de type externe ajoute la définition du type interne, de sorte que le typehash couvre les deux. En termes EIP-712, primaryType est le nom externe, types contient les deux entrées, et message est { account, nonce, action }. L'ordre des champs fait partie de la chaîne de type et doit correspondre exactement.

Points d'entrée de financement non signés​

Tous les appels de financement ne sont pas des actions EIP-712. Ces méthodes sont des transactions directes envoyées par le portefeuille payeur ou le routeur :

function depositUsdcFor(address account, uint256 amount) external;
function depositOption(address account, address token, uint256 amount) external;

depositUsdcFor est volontairement non signé, car msg.sender n'est que le payeur en USDC. Le compte Hypercall crédité est l'argument explicite account et le champ d'événement UsdcDeposit.account. Des routeurs et des zaps peuvent appeler cette méthode, donc les indexeurs et les services backend ne doivent pas utiliser msg.sender pour attribuer le crédit.

depositOption brûle les tokens d'option de msg.sender et émet Deposit(account, msg.sender, token, amount) pour l'indexeur RSM. Le chemin de crédit des options est piloté par les événements et n'utilise aucune signature de manager, d'agent ou du RSM de la part du déposant.

Domaine autonome : cotations de covered calls physiques​

Les cotations de covered calls physiques sont vérifiées par la factory déployée sur la chaîne sélectionnée. Elles n'utilisent ni le vérificateur de l'Exchange ni son domaine à adresse nulle.

Domaine :

{
"name": "Hypercall Physical Covered Call",
"version": "1",
"chainId": "<selected chain id>",
"verifyingContract": "<exact PhysicalCoveredCallFactory address>"
}

Signataire : le market maker encodé dans PhysicalCoveredCallQuote.marketMaker.

Types imbriqués canoniques :

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)

La factory recalcule requestHash à partir de la requête imbriquée complète avant de récupérer le signataire de la cotation. La signature lie donc le vendeur, le wrapper du sous-jacent, le montant de parts du wrapper, le strike, l'échéance, la prime, la date limite de la cotation, le nonce, le chain id et l'adresse de la factory. Le token de règlement et ses décimales relèvent de la configuration de la factory, qui fait autorité, et ne sont pas des valeurs signées séparément. Pyth est absent de cette génération sans oracle. Le digest de la cotation et le nonce du market maker sont tous deux consommés lorsque le vendeur finance un vault.

Seul le vendeur encodé dans la requête peut soumettre la cotation signée. Le financement émet le NFT de créance du vendeur (writer-claim) au profit du vendeur et le NFT d'option longue au profit du market maker coté, à condition que ce market maker soit un destinataire éligible lorsque la liste blanche optionnelle des acheteurs est activée. Une signature valide autorise le financement, pas l'exercice.

Seul le détenteur actuel du NFT d'option longue peut appeler l'exercice. Cette règle réservée au détenteur empêche un opérateur ERC-721 de consommer l'allowance en token de règlement du détenteur. Un opérateur approuvé peut toujours transférer le NFT selon les règles standard ERC-721, ce qui transfère le droit économique à un destinataire éligible lorsque le filtre acheteur est activé. Un exercice réussi prélève le montant du strike auprès de l'appelant détenteur, lui livre le sous-jacent et brûle le NFT d'option longue.

Séparateurs de domaine EIP-712​

Les trois domaines de directives utilisent la même structure et ne diffèrent que par name. Le verifyingContract est l'adresse nulle, donc une même signature est valide pour n'importe quel Account de la chaîne, et c'est l'adresse de l'Account dans le message qui la lie à un Account unique.

{
"name": "<DomainName>",
"version": "1",
"chainId": <chainId>,
"verifyingContract": "0x0000000000000000000000000000000000000000"
}

Le type de domaine est EIP712Domain(string name,string version,uint256 chainId,address verifyingContract).

Chain IDs : réseau principal 999, testnet 998. L'Account sélectionne le séparateur selon la chaîne sur laquelle il s'exécute, donc une signature testnet n'est jamais vérifiée sur le réseau principal.

DomainenameversionSignataireChaîneSéparateur
Portefeuille APIHypercallApiSign1Portefeuille API9990x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb
Portefeuille APIHypercallApiSign1Portefeuille API9980x339bee4c00da9a5361f687797205c8d03f323659f5d9dc9e0505b9437ddee25e
ManagerHypercallManagerSign1Manager9990xc9b5b0b8b0d9d7ba716326acbf795cfe431ef960a25a8f958d6569bea2f1516e
ManagerHypercallManagerSign1Manager9980xd1f76b6138be892c14b71b0569bdb049cb44f239d34c78ef1ffaacd2466f9f18
RSMHypercallRsmSign1Signataire RSM9990x3d0cae2af623c614099dbadd67a1e1457fabde576aa270a70a57e39bf338a7be
RSMHypercallRsmSign1Signataire RSM9980x650b282053fb61d3fd477bdc28f6434311fe905e27cc4ca643e87e802c45938c

Calculez vous-même le séparateur et comparez-le avant de signer quoi que ce soit :

import { ethers } from "ethers";

const separator = ethers.TypedDataEncoder.hashDomain({
name: "HypercallApiSign",
version: "1",
chainId: 999,
verifyingContract: ethers.ZeroAddress
});
// 0x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb

Référence des messages​

Matrice signataires et endpoints​

MessageDomaineSignataireSoumettre àExécute
HLOrderAPIPortefeuille APIPOST /v1/tee-perp/orders/submit, ou POST /v1/actions/hl_limit_orderOrdre limite Hyperliquid
HLCancelAPIPortefeuille APIPOST /v1/tee-perp/cancels/submit-by-oid, ou POST /v1/actions/hl_cancel_by_oidAnnulation par oid
HLCancelByCloidAPIPortefeuille APIPOST /v1/tee-perp/cancels/submit, ou POST /v1/actions/hl_cancel_by_cloidAnnulation par cloid
HCPerpTriggerOrderAPIPortefeuille APIPOST /v1/tee-perp/orders/submit-triggerOrdre déclencheur natif (TEE uniquement)
HCPerpOrderBatchAPIPortefeuille APIPOST /v1/tee-perp/orders/submit-batchLot d'ordres natif (TEE uniquement)
HCPerpLeverageChangeAPIPortefeuille APIPOST /v1/tee-perp/leverage/submitMise à jour du levier (TEE uniquement)
HCPerpScheduleCancelAPIPortefeuille APIPOST /v1/tee-perp/schedule-cancel/submitDead-man switch (TEE uniquement)
HCUpdateApiWalletManagerManagerPOST /v1/actions/hc_update_api_walletRegistre des portefeuilles API de l'Account
HLAddApiWalletManagerManagerPOST /v1/actions/hl_add_api_walletApprobation de portefeuille API HyperCore
HLSendAssetManagerManagerPOST /v1/actions/hl_send_assetsendAsset HyperCore depuis l'Account
HLSetAbstractionManagerManagerPOST /v1/actions/hl_set_abstractionMode de compte HyperCore (unifié uniquement)
HCTransferOptionManagerManagerNon acceptéRéservé, rejeté on-chain
HLOrder, HLCancel, HLCancelByCloid, HLSendAssetRSMSignataire RSMSéquenceur uniquementOrdres de récupération et balayages via l'Account
System*RSMSignataire RSMSéquenceur uniquementCrédits, retraits, liquidation via l'Exchange

Toutes les routes /v1/actions/{action} acceptent account, nonce, action et signature. POST /v1/actions/{action}/typed-data renvoie les données typées exactes à signer pour cette requête, ce qui est le moyen le plus simple de valider votre encodeur. GET /v1/directives/{directive_id} indique le résultat on-chain. Les schémas de requête se trouvent dans la Référence API.

Conventions de transmission​

  • nonce et tous les champs uint64, uint128 ou uint256 sont des entiers JSON jusqu'à 9007199254740991, ou des chaînes décimales. Utilisez des chaînes au-delà.
  • signature est une chaîne hexadécimale 0x de 65 octets (r || s || v). v peut valoir 0, 1, 27 ou 28.
  • Les champs bytes32 sont en hexadécimal de 32 octets préfixé par 0x. Les adresses sont en hexadécimal avec checksum ou en minuscules.
  • Les prix et tailles perp sont les entiers HyperCore 1e8, par exemple $50,000 correspond à 5000000000000 et 0.001 coin à 100000.

Directives du portefeuille API (HypercallApiSign)​

Signées par un portefeuille API actif de l'Account. Utilisez le chain ID 999 et le name HypercallApiSign.

Les vecteurs de test utilisent un compte fictif et un nonce fixe afin que vous puissiez vérifier votre encodeur octet par octet. Le digest est keccak256(0x1901 || domainSeparator || directiveStructHash).

HLOrder​

Un ordre limite Hyperliquid pour l'Account.

Structure :

struct LimitOrder {
uint32 asset;
bool isBuy;
uint64 limitPx;
uint64 sz;
bool reduceOnly;
uint8 encodedTif;
uint128 cloid;
}

struct HLOrder {
address account;
uint64 nonce;
LimitOrder action;
}

Type EIP-712 canonique :

HLOrder(address account,uint64 nonce,LimitOrder action)LimitOrder(uint32 asset,bool isBuy,uint64 limitPx,uint64 sz,bool reduceOnly,uint8 encodedTif,uint128 cloid)

Typehash : 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd. Signataire : portefeuille API. Action : version 1, id 1.

  • asset : l'indice d'actif Hyperliquid. GET /v1/tee-perp/markets liste les marchés perp acceptés par Hypercall et leurs indices.
  • isBuy : true pour acheter, false pour vendre.
  • limitPx, sz : prix et taille multipliés par 1e8.
  • reduceOnly : true si l'ordre ne peut que réduire une position.
  • encodedTif : ALO = 1, GTC = 2, IOC = 3. Toute autre valeur est rejetée.
  • cloid : identifiant d'ordre client, non nul. Vous l'utilisez ensuite pour annuler par cloid.

Exemple (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);

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd
Hash de la structure d'action0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41
Hash de la structure de directive0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703
Digest à signer0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5

Le vecteur de test utilise isBuy: true, limitPx: 5000000000000, sz: 100000, reduceOnly: false, encodedTif: 2, asset: 0, et cloid égal au nonce.

Soumission : POST /v1/tee-perp/orders/submit avec account, nonce, action et signature. Hypercall effectue la vérification de marge, puis une enclave sécurisée signe et envoie l'ordre Hyperliquid natif avec le builder code Hypercall attaché. Le manager de l'Account doit d'abord approuver ce builder avec Account.approveZeroFeeBuilder ; voir Onboarding. Voir Perps pour le flux complet.

{
"account": "0x1111111111111111111111111111111111111111",
"nonce": 1760000000000,
"action": {
"asset": 0,
"isBuy": true,
"limitPx": "5000000000000",
"sz": "100000",
"reduceOnly": false,
"encodedTif": 2,
"cloid": "1760000000000"
},
"signature": "0x<65 byte signature>"
}

Le même message signé est également accepté sur POST /v1/actions/hl_limit_order, qui l'encode en directive on-chain exécutée via Exchange.executeUserDirective et Account.performCoreAction.

HLCancel​

Annule un ordre par son identifiant d'ordre Hyperliquid. L'enveloppe est HLCancel et la structure interne est 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. Signataire : portefeuille API. Action : version 1, id 10. Soumission : POST /v1/tee-perp/cancels/submit-by-oid, ou 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);

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85
Hash de la structure d'action0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727
Hash de la structure de directive0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097
Digest à signer0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330

Le vecteur de test utilise asset: 0 et oid: 123456789.

HLCancelByCloid​

Annule un ordre par l'identifiant d'ordre client que vous avez défini sur 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. Signataire : portefeuille API. Action : version 1, id 11. Soumission : POST /v1/tee-perp/cancels/submit, ou 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);

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5
Hash de la structure d'action0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0
Hash de la structure de directive0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d
Digest à signer0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d

Le vecteur de test utilise asset: 0 et cloid: 1760000000000.

Messages perp réservés au TEE​

Ces quatre messages sont vérifiés par l'API Hypercall et non par le contrat Account, car l'enclave les exécute nativement sur Hyperliquid et aucune directive on-chain n'existe pour eux. Ils utilisent le même domaine HypercallApiSign et la même autorisation de portefeuille API que HLOrder (le signataire doit être un portefeuille API actif de l'Account, et l'Account doit être en marge de portefeuille). Leurs typehashes ne figurent pas dans les contrats. Les nonces sont un temps Unix en millisecondes.

PerpOrderTerms​

HCPerpTriggerOrder et HCPerpOrderBatch intègrent tous deux cette structure. Un ordre enfant limite signe son octet TIF avec triggerPx = 0, isMarket = false, tpsl = 0. Un ordre enfant déclencheur signe encodedTif = 0, un triggerPx positif, et tpsl égal à 1 (take profit) ou 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​

Un ordre stop-loss ou take-profit, soumis à POST /v1/tee-perp/orders/submit-trigger. Le champ action.orderType de la requête doit être un déclencheur.

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

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c
Hash de la structure d'action0x285b3186be219b92d7159419288c0dce9bc4ad7bfc9536e009ebf24bd67f434c
Hash de la structure de directive0xaa03e40b34b15e7e932ae827921930e7538387b596ef1040dbcc791e69021299
Digest à signer0xc46aadc390b66c235af15e199e188ab23fb7f7f1b9237f6c2849c264c28d94da

Le vecteur de test est une vente stop-loss au marché en reduce-only : asset: 0, isBuy: false, limitPx: 4800000000000 (pire prix), sz: 100000, reduceOnly: true, encodedTif: 0, triggerPx: 4900000000000, isMarket: true, tpsl: 2, cloid: 1760000000001.

HCPerpOrderBatch​

Jusqu'à 100 ordres sous un même regroupement, soumis à POST /v1/tee-perp/orders/submit-batch. Chaque ordre doit utiliser un cloid distinct. grouping vaut 0 (aucun regroupement), 1 (normalTpsl) ou 2 (positionTpsl). Un lot compte comme un seul placement d'ordre au regard de la limite de débit.

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. Le tableau orders est encodé comme le keccak256 de la concaténation des hashs de structure PerpOrderTerms, dans l'ordre de soumission.

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b
Hash du tableau d'ordres0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98
Hash de la structure de directive0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0
Digest à signer0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07

Le vecteur de test est grouping: 1 avec deux ordres : un achat limite GTC (limitPx: 5000000000000, sz: 100000, cloid: 1760000000000) suivi du stop-loss de l'exemple d'ordre déclencheur.

HCPerpLeverageChange​

Définit le levier pour un actif, soumis à POST /v1/tee-perp/leverage/submit. leverage doit être strictement supérieur à zéro.

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

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463
Hash de la structure d'action0x0e6e271dd56192d7fb1f37ea2eaffecfbbe2d1f79cac78dce6a6930bb8cc253e
Hash de la structure de directive0xe04b169bbb0e20042308e5aad1036ce60eda75f484a4d6093dc60f2c2231129e
Digest à signer0xb2a43487152a7cecc73d2b6b84d817a58dd02c559b05289a8d8e1b5c3d25e266

Le vecteur de test fixe un levier cross de 5x sur asset: 0.

HCPerpScheduleCancel​

Le dead-man switch de Hyperliquid : annule tous les ordres ouverts à time (millisecondes Unix, au moins sept secondes dans le futur). Soumis à POST /v1/tee-perp/schedule-cancel/submit. Pour supprimer une annulation programmée, omettez time dans la requête et signez time = 0. L'envoi explicite de 0 est rejeté.

struct PerpScheduleCancel {
uint64 time;
}

struct HCPerpScheduleCancel {
address account;
uint64 nonce;
PerpScheduleCancel action;
}
HCPerpScheduleCancel(address account,uint64 nonce,PerpScheduleCancel action)PerpScheduleCancel(uint64 time)

Typehash : 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
Hash de la structure d'action0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc
Hash de la structure de directive0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b
Digest à signer0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc

Le vecteur de test programme une annulation à time: 1760000060000.

Annulation préparée signée par le manager​

POST /v1/tee-perp/cancels/submit-prepared est le chemin d'annulation signé par le manager. Il n'utilise pas de structure de données typées. Le manager signe le digest d'une annulation Hyperliquid native préparée, fournie sous forme de preparedRequest (base64) avec managerSignature en forme canonique low-s, ainsi qu'une authenticationSignature horodatée qui authentifie le portefeuille du manager. Voir la Référence API pour le schéma de la requête.

Directives du manager (HypercallManagerSign)​

Signées par le manager de l'Account. Utilisez le chain ID 999 et le name HypercallManagerSign. L'Account exige signer == manager. Soumettez avec POST /v1/actions/{action}.

HCUpdateApiWallet​

Ajoute, remplace ou supprime (addr = 0x0) le portefeuille API enregistré sous name sur l'Account.

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. Action : version 0, id 2. Soumission : POST /v1/actions/hc_update_api_wallet avec une action de la forme { "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);

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257
Hash de la structure d'action0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7
Hash de la structure de directive0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5
Digest à signer0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8

Le vecteur de test utilise le name trading-bot (0x74726164696e672d626f74 complété à droite par des zéros) et l'addr 0x2222222222222222222222222222222222222222. Voir Onboarding pour le flux complet du portefeuille API. L'Account émet ApiWalletUpdated(name, addr).

HLAddApiWallet​

Approuve un portefeuille API Hyperliquid pour l'Account sur 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. Action : version 1, id 9. Soumission : POST /v1/actions/hl_add_api_wallet.

apiWalletName est une string, donc son champ de structure est keccak256(bytes(apiWalletName)). Ethers et viem le font pour vous.

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2
Hash de la structure d'action0xed32a441b0ee59c0252f5dff3411766289c9c35c19e3152b0b2b204176c2c7cd
Hash de la structure de directive0xb990a3dfb4e8d96243539f8758b3a55249b217542bb4112f4f88ed67ec516ed9
Digest à signer0x584886d020316085de0e0dec16331b8e990558be3e8fd004c47200abbebed518

Le vecteur de test utilise l'apiWalletAddress 0x2222222222222222222222222222222222222222 et l'apiWalletName hl-bot.

HLSendAsset​

Envoie des actifs depuis l'Account sur HyperCore vers une destination.

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. Action : version 1, id 13. Soumission : 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);

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595
Hash de la structure d'action0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656
Hash de la structure de directive0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08
Digest à signer0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10

Le vecteur de test envoie 5 USDC (amountWei: 500000000) des perps (srcDex: 0) vers le spot (dstDex: 4294967295) avec pour destination l'Exchange de production 0xE6b7FaA216cabb2b38B392f577C9c826378b2240.

HLSetAbstraction​

Définit le mode de compte HyperCore de l'Account. L'Account n'accepte que user égal à lui-même et abstraction = 2 (compte unifié) ; toute autre valeur provoque un revert. La marge de portefeuille (Portfolio Margin) l'exige.

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. Action : version 1, id 16. Soumission : POST /v1/actions/hl_set_abstraction.

Vecteur de test (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786
Hash de la structure d'action0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e
Hash de la structure de directive0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d
Digest à signer0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d

Le vecteur de test définit user sur l'Account et abstraction à 2.

HCTransferOption (réservé)​

Les contrats définissent HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei) (typehash 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819, version d'action 0, id 1), mais aucun type de signataire ne lui est attribué. L'Account effectue un revert avec Account__UserDirectiveNotSupported, et l'API rejette hc_transfer_option. Ne le signez pas. Déplacez les tokens d'option avec depositOption et les retraits à la place.

Transactions du manager sans signature​

Certaines actions du manager sont des appels directs à l'Account, et non des messages EIP-712 : Account.approveZeroFeeBuilder(builder) approuve un builder Hyperliquid avec des frais maximum de 0 % et doit être appelé une fois avant le premier ordre perp (voir Onboarding). Account.transferTo(recipient, token, amount) transfère des tokens hors de l'Account sur HyperEVM. Les deux exigent msg.sender == manager et effectuent un revert tant que l'Account est en liquidation.

Directives RSM (HypercallRsmSign)​

Signées par le signataire RSM et soumises par le séquenceur. Elles créditent les dépôts, traitent les retraits, démarrent et arrêtent les liquidations, et placent des ordres de récupération IOC reduce-only. Les market makers et les utilisateurs ne les signent ni ne les soumettent ; elles sont documentées afin que vous puissiez vérifier ce que le protocole peut faire à un Account. Utilisez le chain ID 999 et le name HypercallRsmSign. L'Exchange vérifie signer == rsmSigner (actuellement 0x502E7fAbF34E84EeB115C34FE947b79A94dF886E sur le réseau principal) et l'appelant doit détenir le SEQUENCER_ROLE.

Ordres et balayages RSM (exécutés par l'Account)​

Ils réutilisent les structures HL sous le domaine RSM, donc les typehashes sont identiques à ceux de l'API et du manager, seul le séparateur de domaine diffère. L'Account applique des contraintes supplémentaires et les exécute même pendant une liquidation.

MessageTypehashContrainte appliquée par l'Account
HLOrder0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707ddencodedTif doit être IOC (3), et l'ordre doit être reduceOnly, ou une vente spot contre USDC (identifiants d'actifs spot de 10000 à 99999) limitée à 5 % au plus sous le prix spot HyperCore
HLCancel0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85Aucune
HLCancelByCloid0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5Aucune
HLSendAsset0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595destination doit être l'Exchange

Vecteur de test RSM HLOrder (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd
Hash de la structure d'action0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db
Hash de la structure de directive0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3
Digest à signer0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469

Le vecteur RSM HLOrder est une vente IOC reduce-only (isBuy: false, limitPx: 4800000000000, sz: 100000, reduceOnly: true, encodedTif: 3, cloid égal au nonce). Exchange.executeRsmDirective vérifie la signature et transmet l'action à l'Account.

Actions système (exécutées par l'Exchange)​

Version 255. Chaque enveloppe est de la forme System<Action>(address account,uint64 nonce,<Action> action)<Action>(...).

EnveloppeType interneTypehash
SystemCreditTokenCreditToken(uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052
SystemCreditOptionCreditOption(bytes32 underlying,uint256 expiry,uint256 strike,bool isCall,uint256 amountWei)0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae
SystemStartLiquidationStartLiquidation(int256 equity,uint256 marginNeeded)0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e
SystemStopLiquidationStopLiquidation(uint256 startTime)0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3
SystemWithdrawTokenWithdrawToken(address destination,address subAccount,uint32 srcDex,uint32 dstDex,uint64 token,uint64 amountWei)0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883

Chaînes de type externes complètes :

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 crédite l'Account de tokens spot ou perp depuis HyperCore. amountWei doit être non nul et l'Account doit être activé sur HyperCore.
  • SystemCreditOption émet des tokens d'option au profit de l'Account, en déployant la paire d'options si nécessaire. underlying est un mot OpenZeppelin ShortString : ASCII aligné à gauche avec la longueur en octets dans le dernier octet (BTC vaut 0x42544300...03). Les encodages non canoniques provoquent un revert.
  • SystemStartLiquidation enregistre les paramètres d'enchère et verrouille l'Account. marginNeeded doit être non nul.
  • SystemStopLiquidation exige que startTime soit égal au début enregistré et rend l'Account à son manager.
  • SystemWithdrawToken met en file d'attente une livraison de Standard USDC sur HyperCore depuis le solde propre de l'Exchange. Il exige subAccount = 0, srcDex = 0, un dstDex égal à 0 ou 4294967295, token = 0 (USDC), et un amountWei multiple entier de l'unité EVM. Un reçu HyperEVM seul ne prouve pas la livraison sur HyperCore.

Vecteur de test SystemCreditToken (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052
Hash de la structure d'action0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011
Hash de la structure de directive0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1
Digest à signer0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254

Le vecteur crédite 5 USDC (srcDex et dstDex égaux à 4294967295, token: 0, amountWei: 500000000).

Vecteur de test SystemCreditOption (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae
Hash de la structure d'action0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6
Hash de la structure de directive0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554
Digest à signer0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2

Le vecteur crédite un call BTC (underlying: 0x42544300...03, expiry: 1761811200, strike: 80000, isCall: true, amountWei: 1000000000000000000).

Vecteur de test SystemStartLiquidation (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e
Hash de la structure d'action0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803
Hash de la structure de directive0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5
Digest à signer0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b

Le vecteur utilise equity: -1500000000 et marginNeeded: 20000000000 (tous deux en USDC à six décimales).

Vecteur de test SystemStopLiquidation (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3
Hash de la structure d'action0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b
Hash de la structure de directive0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40
Digest à signer0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af

Le vecteur utilise startTime: 1760000000.

Vecteur de test SystemWithdrawToken (compte 0x1111111111111111111111111111111111111111, nonce 1760000000000, chaîne 999) :

ÉtapeValeur
Typehash0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883
Hash de la structure d'action0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076
Hash de la structure de directive0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2
Digest à signer0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c

Le vecteur retire 5 USDC (amountWei: 500000000) vers la destination 0x1111111111111111111111111111111111111111 avec srcDex: 0, dstDex: 0, token: 0.

Nonces​

Chaque signataire dispose d'un espace de nonces indépendant, suivi à trois endroits.

  • Contrat Account : un bitmap par signataire. Account.isNonceUsed(signer, nonce) indique si un nonce a été consommé. Une directive utilisateur effectue un revert avec Account__NonceAlreadyUsed en cas de réutilisation. Il n'existe pas de nextNonce ; les trous sont autorisés et l'ordre n'a pas d'importance on-chain.
  • Contrat Exchange : un bitmap pour le signataire RSM, consultable avec Exchange.isNonceUsed(signer, nonce).
  • Moteur : conserve les 100 nonces les plus élevés par signataire. Un nouveau nonce ne doit pas figurer dans cet ensemble, doit dépasser le plus petit nonce stocké une fois l'ensemble plein, et doit se situer strictement entre deux jours avant et un jour après l'heure du serveur en millisecondes.

Utilisez l'heure Unix actuelle en millisecondes comme base du nonce et incrémentez-la par signataire. Deux requêtes signées par le même portefeuille dans la même milliseconde nécessitent des nonces distincts, donc tenez un compteur. Pour les routes perp TEE, le nonce sert aussi d'ancre temporelle de la requête : utilisez donc de vrais horodatages en millisecondes plutôt que de petits entiers.

function isNonceUsed(address signer, uint256 nonce) external view returns (bool);

Flux de vérification des signatures​

  1. Hors chaîne : le signataire construit le digest EIP-712 (0x1901 || domainSeparator || structHash) et le signe.
  2. API : Hypercall récupère le signataire, vérifie qu'il s'agit d'un portefeuille API actif ou du manager, effectue la vérification de marge du moteur pour les ordres, puis met la directive en file d'attente. La réponse indique l'étape réelle, les détails d'un éventuel rejet et le hash de transaction.
  3. Séquenceur : soumet Exchange.executeUserDirective(directive, signature). L'Exchange vérifie que l'Account existe et transmet à Account.executeUserDirective.
  4. Account : reconstruit le digest à partir de sa propre adresse, du nonce et de l'action, récupère le signataire avec le séparateur API ou manager correspondant à cette action, vérifie l'autorisation, consomme le nonce, puis exécute. Les actions HL vont au CoreWriter de HyperCore. Les actions HC mettent à jour le registre des portefeuilles API.
  5. Client : interroge GET /v1/directives/{directive_id} pour obtenir le statut final.

Les routes perp TEE s'arrêtent après l'étape API : c'est l'enclave, et non l'Account, qui exécute l'ordre sur Hyperliquid.

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

Éléments obsolètes et supprimés​

Ces éléments figuraient dans des versions antérieures de cette page et ne font plus partie du système déployé. Ils sont listés afin que les intégrations qui en dépendent puissent être migrées.

  • Encodage Processor et ActionCaster. Le contrat Processor et l'encodage des messages ActionCaster ont été supprimés dans Exchange 0.2.0 (février 2026). Les directives Account passent désormais par Exchange.executeUserDirective et le CoreWriter. L'Exchange 0.6.1 déployé ne possède aucun des anciens points d'entrée.
  • Points d'entrée de l'Exchange avec leurs propres structures. hlRequestOrder, hlRequestCancel, hlRequestCancelByCloid, hlActionSendAsset, hcActionWithdrawToken, hcActionWithdrawOption, rsmCommandRebalance et rsmCommandRepay n'existent plus. Leurs remplaçants :
Message suppriméRemplacement
HLRequestCancel (lot de HLCancel{asset,oid} plus nonce)HLCancel avec un CancelOrderByOid par directive
HLRequestCancelByCloidHLCancelByCloid avec un CancelOrderByCloid par directive
HLActionSendAsset (account, nonce, destination, srcDex, dstDex, token, amountWei)HLSendAsset avec SendAsset, qui ajoute subAccount
HCActionWithdrawTokenSystemWithdrawToken signé par le RSM, exécuté par le séquenceur après approbation du retrait par le moteur
HCActionWithdrawOptionLes crédits d'options sont des SystemCreditOption RSM ; les dépôts utilisent depositOption
RsmCommandRebalanceHLOrder signé par le RSM (IOC reduce-only)
RsmCommandRepayHLSendAsset signé par le RSM vers l'Exchange
  • Anciennes fonctions d'ordres. placeCoreOrders, cancelCoreOrders et cancelCoreOrdersByCloid utilisaient un encodage MsgPack et le domaine CoreSignatures ("Exchange", chain ID 1337). Elles sont supprimées.
  • nextNonce. Le compteur on-chain nextNonce[signer] n'existe plus. Seul le bitmap des nonces utilisés (isNonceUsed) subsiste.
  • Séparateurs du réseau principal marqués TBD. Le texte précédent indiquait les séparateurs du réseau principal pour le manager et le RSM comme TBD. Les trois sont fixés et listés ci-dessus.
  • HCTransferOption. Défini mais jamais activé ; voir ci-dessus.

Considérations de sécurité​

  1. Clés : conservez la clé du manager sur un portefeuille matériel. Les portefeuilles API ne signent que les ordres et les annulations ; utilisez des clés distinctes pour chaque système.
  2. Rejeu de nonce : ne réutilisez jamais un nonce. Suivez les nonces hors chaîne et incrémentez-les de manière atomique.
  3. Domaine : signez toujours avec le chain ID 999 sur le réseau principal (998 sur testnet), et comparez le séparateur que vous calculez au tableau ci-dessus.
  4. Vérifiez ce que vous signez : appelez POST /v1/actions/{action}/typed-data et comparez le résultat avec votre propre encodeur avant de signer avec un portefeuille matériel.
  5. La vérification on-chain fait foi : l'API pré-vérifie les signatures, mais l'Account revérifie chaque directive on-chain. Ne considérez pas un accusé de réception de l'API comme une exécution.
  6. Manager ou portefeuille API : les managers contrôlent la propriété, les portefeuilles API et les mouvements d'actifs. Les portefeuilles API ne signent que des messages de trading. Utilisez des clés distinctes.

Références​