Esta página fue traducida automáticamente. El original en inglés es la versión canónica. Leer en inglés →
Saltar al contenido principal

Firma EIP-712

Esta página es la referencia a nivel de campo de cada mensaje EIP-712 que Hypercall verifica: los tres dominios de firma de directivas (API wallet, Manager, RSM), los mensajes de perpetuos exclusivamente off-chain que comparten el dominio de la API wallet, y el dominio independiente Physical Covered Call Quote. Las órdenes de opciones en la API REST usan un dominio distinto, Hypercall; consulte Autenticación y firma.

Todo lo aquí descrito se verificó contra los contratos desplegados en la mainnet de HyperEVM (chain ID 999): Exchange 0.6.1 en 0xE6b7FaA216cabb2b38B392f577C9c826378b2240 y Account 0.2.4. Los separadores de dominio y typehashes que se indican a continuación están incrustados en ese bytecode desplegado.

Descripción general​

Una directiva es una acción sobre un Account, firmada off-chain y enviada on-chain por el sequencer de Hypercall mediante Exchange.executeUserDirective o Exchange.executeRsmDirective. El Account recupera el firmante a partir del digest EIP-712 y verifica la autorización:

  1. API wallet: una dirección registrada en el Account con hc_update_api_wallet (Account.isApiWalletActive). Firma órdenes y cancelaciones.
  2. Manager: el propietario del Account (Account.manager). Firma cambios de API wallet, envíos de activos y cambios de modo de cuenta.
  3. Firmante RSM: controlado por el protocolo (Exchange.rsmSigner). Firma créditos, retiros, directivas de liquidación y órdenes de recuperación reduce-only. Los usuarios nunca las firman.

Codificación de directivas​

On-chain, una directiva es abi.encodePacked(account, nonce, version, id, data):

BytesCampoSignificado
20accountLa dirección del Account (address)
8nonceEl nonce del firmante (uint64)
1versionFamilia de acciones
3idID de la acción dentro de la familia
restodataabi.encode del struct interno de la acción
VersiónFamiliaIDs de acción
0HyperCall (HC)2 actualizar API wallet. 1 (transferir opción) está reservado y se rechaza.
1HyperLiquid (HL)1 orden límite, 9 añadir API wallet, 10 cancelar por oid, 11 cancelar por cloid, 13 enviar activo, 16 establecer abstracción
255Sistema1 acreditar token, 2 acreditar opción, 3 iniciar liquidación, 4 detener liquidación, 5 retirar token

Usted no construye esta cadena de bytes. Firme los datos tipados y luego envíe account, nonce, action y signature a la API, que codifica la directiva.

Estructura de los datos tipados​

Toda directiva tiene la misma estructura externa: la dirección del Account, el nonce del firmante y un struct interno de acción.

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

La cadena del tipo externo añade la definición del tipo interno, de modo que el typehash cubre ambos. En términos de EIP-712, primaryType es el nombre externo, types contiene ambas entradas y message es { account, nonce, action }. El orden de los campos forma parte de la cadena de tipo y debe coincidir exactamente.

Puntos de entrada de fondeo sin firma​

No toda llamada de fondeo es una acción EIP-712. Estos métodos son transacciones directas enviadas por la wallet o el router que paga:

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

depositUsdcFor no lleva firma de forma intencional, porque msg.sender es solo quien paga el USDC. La cuenta de Hypercall acreditada es el argumento explícito account y el campo UsdcDeposit.account del evento. Los routers y zaps pueden llamar a este método, por lo que los indexadores y servicios de backend no deben usar msg.sender para atribuir el crédito.

depositOption quema tokens de opciones de msg.sender y emite Deposit(account, msg.sender, token, amount) para el indexador RSM. La ruta de crédito de opciones se basa en eventos y no utiliza ninguna firma de manager, agente o RSM del depositante.

Dominio independiente: cotizaciones de covered calls físicas​

Las cotizaciones de covered calls físicas las verifica la factory desplegada en la cadena seleccionada. No usan el verificador del Exchange ni su dominio con dirección cero.

Dominio:

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

Firmante: el market maker codificado en PhysicalCoveredCallQuote.marketMaker.

Tipos anidados canónicos:

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 recalcula requestHash a partir de la solicitud anidada completa antes de recuperar el firmante de la cotización. Por lo tanto, la firma vincula al vendedor, el wrapper del activo subyacente, la cantidad de participaciones del wrapper, el strike, el vencimiento, la prima, el plazo de la cotización, el nonce, el chain id y la dirección de la factory. El token de settlement y sus decimales son configuración autoritativa de la factory, no valores firmados por separado. Pyth no forma parte de esta generación sin oráculo. Tanto el digest de la cotización como el nonce del maker se consumen cuando el vendedor fondea un vault.

Solo el vendedor codificado en la solicitud puede enviar la cotización firmada. El fondeo emite el NFT de derecho del emisor (writer-claim) al vendedor y el NFT de la opción larga al market maker cotizado, siempre que ese maker sea un destinatario elegible mientras la allowlist opcional de compradores esté activa. Una firma válida autoriza el fondeo, no el ejercicio.

Solo el propietario actual del NFT de la opción larga puede llamar al ejercicio. Esta regla de solo propietario impide que un operador ERC-721 consuma el allowance del token de settlement del propietario. Un operador aprobado aún puede transferir el NFT según las reglas estándar de ERC-721, lo que transfiere el derecho económico a un destinatario elegible mientras la restricción de compradores esté activa. Un ejercicio exitoso toma el efectivo del strike del propietario que llama, entrega el activo subyacente a ese propietario y quema el NFT de la opción larga.

Separadores de dominio EIP-712​

Los tres dominios de directivas usan la misma estructura y difieren solo en name. El verifyingContract es la dirección cero, por lo que la misma firma es válida para cualquier Account de la cadena; es la dirección del Account dentro del mensaje la que la vincula a un único Account.

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

El tipo de dominio es EIP712Domain(string name,string version,uint256 chainId,address verifyingContract).

Chain IDs: mainnet 999, testnet 998. El Account selecciona el separador según la cadena en la que se ejecuta, por lo que una firma de testnet nunca se verifica en mainnet.

DominionameversionFirmanteCadenaSeparador
API walletHypercallApiSign1API wallet9990x462ae8a3a67da57ddd088e60be368536f992b8bf369d13e64e620c51993e5ebb
API walletHypercallApiSign1API wallet9980x339bee4c00da9a5361f687797205c8d03f323659f5d9dc9e0505b9437ddee25e
ManagerHypercallManagerSign1Manager9990xc9b5b0b8b0d9d7ba716326acbf795cfe431ef960a25a8f958d6569bea2f1516e
ManagerHypercallManagerSign1Manager9980xd1f76b6138be892c14b71b0569bdb049cb44f239d34c78ef1ffaacd2466f9f18
RSMHypercallRsmSign1Firmante RSM9990x3d0cae2af623c614099dbadd67a1e1457fabde576aa270a70a57e39bf338a7be
RSMHypercallRsmSign1Firmante RSM9980x650b282053fb61d3fd477bdc28f6434311fe905e27cc4ca643e87e802c45938c

Calcule el separador usted mismo y compárelo antes de firmar cualquier cosa:

import { ethers } from "ethers";

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

Referencia de mensajes​

Matriz de firmantes y endpoints​

MensajeDominioFirmanteEnviar aEjecuta
HLOrderAPIAPI walletPOST /v1/tee-perp/orders/submit, o POST /v1/actions/hl_limit_orderOrden límite en Hyperliquid
HLCancelAPIAPI walletPOST /v1/tee-perp/cancels/submit-by-oid, o POST /v1/actions/hl_cancel_by_oidCancelación por oid
HLCancelByCloidAPIAPI walletPOST /v1/tee-perp/cancels/submit, o POST /v1/actions/hl_cancel_by_cloidCancelación por cloid
HCPerpTriggerOrderAPIAPI walletPOST /v1/tee-perp/orders/submit-triggerOrden trigger nativa (solo TEE)
HCPerpOrderBatchAPIAPI walletPOST /v1/tee-perp/orders/submit-batchLote de órdenes nativo (solo TEE)
HCPerpLeverageChangeAPIAPI walletPOST /v1/tee-perp/leverage/submitActualización de apalancamiento (solo TEE)
HCPerpScheduleCancelAPIAPI walletPOST /v1/tee-perp/schedule-cancel/submitDead-man switch (solo TEE)
HCUpdateApiWalletManagerManagerPOST /v1/actions/hc_update_api_walletRegistro de API wallets del Account
HLAddApiWalletManagerManagerPOST /v1/actions/hl_add_api_walletAprobación de API wallet en HyperCore
HLSendAssetManagerManagerPOST /v1/actions/hl_send_assetsendAsset de HyperCore desde el Account
HLSetAbstractionManagerManagerPOST /v1/actions/hl_set_abstractionModo de cuenta en HyperCore (solo unificada)
HCTransferOptionManagerManagerNo aceptadoReservado, rechazado on-chain
HLOrder, HLCancel, HLCancelByCloid, HLSendAssetRSMFirmante RSMSolo el sequencerÓrdenes de recuperación y barridos a través del Account
System*RSMFirmante RSMSolo el sequencerCréditos, retiros y liquidación a través del Exchange

Todas las rutas /v1/actions/{action} reciben account, nonce, action y signature. POST /v1/actions/{action}/typed-data devuelve los datos tipados exactos a firmar para esa solicitud, que es la forma más sencilla de verificar su codificador. GET /v1/directives/{directive_id} informa el resultado on-chain. Los esquemas de solicitud se encuentran en la Referencia de la API.

Convenciones de transmisión​

  • nonce y todo campo uint64, uint128 o uint256 son enteros JSON de hasta 9007199254740991, o cadenas decimales. Use cadenas por encima de ese valor.
  • signature es una cadena hexadecimal 0x de 65 bytes (r || s || v). v puede ser 0, 1, 27 o 28.
  • Los campos bytes32 son hexadecimales de 32 bytes con prefijo 0x. Las direcciones van en hexadecimal con checksum o en minúsculas.
  • Los precios y tamaños de perpetuos son los enteros 1e8 de HyperCore; por ejemplo, $50,000 es 5000000000000 y 0.001 monedas es 100000.

Directivas de API wallet (HypercallApiSign)​

Las firma una API wallet activa del Account. Use chain ID 999 y name HypercallApiSign.

Los vectores de prueba usan una cuenta de ejemplo y un nonce fijo para que usted pueda verificar su codificador byte a byte. El digest es keccak256(0x1901 || domainSeparator || directiveStructHash).

HLOrder​

Una orden límite de Hyperliquid para el 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;
}

Tipo EIP-712 canónico:

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

Typehash: 0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd. Firmante: API wallet. Acción: versión 1, id 1.

  • asset: el índice de activo de Hyperliquid. GET /v1/tee-perp/markets lista los mercados de perpetuos que Hypercall acepta y sus índices.
  • isBuy: true para comprar, false para vender.
  • limitPx, sz: precio y tamaño multiplicados por 1e8.
  • reduceOnly: true si la orden solo puede reducir una posición.
  • encodedTif: ALO = 1, GTC = 2, IOC = 3. Cualquier otro valor se rechaza.
  • cloid: ID de orden del cliente, distinto de cero. Se usa después para cancelar por cloid.

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

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd
Hash del struct de la acción0x0fd024c6bf8f132123e63a78d50008d8c39c52e5409ef6ca87a4eec8f6eabb41
Hash del struct de la directiva0xd32948ee1f249b96124a6acdb5845d09aad8228512098598de6858d5484fe703
Digest a firmar0xc3c42699092fe20c7dbc4205a1027f55c28d33a682a64bd3f04e40f1d28693f5

El vector de prueba usa isBuy: true, limitPx: 5000000000000, sz: 100000, reduceOnly: false, encodedTif: 2, asset: 0 y cloid igual al nonce.

Envío: POST /v1/tee-perp/orders/submit con account, nonce, action y signature. Hypercall ejecuta la verificación de margen y luego un enclave seguro firma y envía la orden nativa de Hyperliquid con el builder code de Hypercall adjunto. El manager del Account debe aprobar primero ese builder con Account.approveZeroFeeBuilder; consulte Onboarding. Consulte Perpetuos para el flujo completo.

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

El mismo mensaje firmado también se acepta en POST /v1/actions/hl_limit_order, que lo codifica como una directiva on-chain ejecutada mediante Exchange.executeUserDirective y Account.performCoreAction.

HLCancel​

Cancela una orden por su ID de orden de Hyperliquid. El wrapper es HLCancel y el struct interno es 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. Firmante: API wallet. Acción: versión 1, id 10. Envío: POST /v1/tee-perp/cancels/submit-by-oid, o 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);

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85
Hash del struct de la acción0xa34e7bb8af0d099f9c48095924e53067bcb9b542a816445b96abebbc5646b727
Hash del struct de la directiva0x69d560ba5ef3e88459bde7fb8252e55dbc33627373c8f0cfcf8ef0868f59e097
Digest a firmar0x5046aba9fb33c55ce736faf63734ea66914f3f168ff0aff2229fa6f31fa9b330

El vector de prueba usa asset: 0 y oid: 123456789.

HLCancelByCloid​

Cancela una orden por el ID de orden del cliente que usted estableció en 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. Firmante: API wallet. Acción: versión 1, id 11. Envío: POST /v1/tee-perp/cancels/submit, o 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);

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5
Hash del struct de la acción0xfa4ab6440f946a6e279d90972d71223c768c01c8a91dc22703a6448dbcb966d0
Hash del struct de la directiva0x998efb01bb9c842eea80e8cc084b9e4e7ec13b2111790e1acbfec32e49060d9d
Digest a firmar0x56af82a6aa7fa50907a23c6cfe3aa556af5aa087b1157163ebf6ea0240e8d29d

El vector de prueba usa asset: 0 y cloid: 1760000000000.

Mensajes de perpetuos exclusivos de TEE​

Estos cuatro mensajes los verifica la API de Hypercall, no el contrato Account, porque el enclave los ejecuta de forma nativa en Hyperliquid y no existe una directiva on-chain para ellos. Usan el mismo dominio HypercallApiSign y la misma autorización de API wallet que HLOrder (el firmante debe ser una API wallet activa del Account, y el Account debe estar en portfolio margin). Sus typehashes no están en los contratos. Los nonces son tiempo Unix en milisegundos.

PerpOrderTerms​

Tanto HCPerpTriggerOrder como HCPerpOrderBatch incluyen este struct. Una orden hija límite firma su byte de TIF con triggerPx = 0, isMarket = false, tpsl = 0. Una orden hija trigger firma encodedTif = 0, un triggerPx positivo y tpsl igual a 1 (take profit) o 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​

Una orden stop-loss o take-profit, enviada a POST /v1/tee-perp/orders/submit-trigger. El action.orderType de la solicitud debe ser un trigger.

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

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x2d3104ab255275839aad254429e4be789f64a8d16b8e3e7d5f30a0db3c887b5c
Hash del struct de la acción0x285b3186be219b92d7159419288c0dce9bc4ad7bfc9536e009ebf24bd67f434c
Hash del struct de la directiva0xaa03e40b34b15e7e932ae827921930e7538387b596ef1040dbcc791e69021299
Digest a firmar0xc46aadc390b66c235af15e199e188ab23fb7f7f1b9237f6c2849c264c28d94da

El vector de prueba es una venta stop-loss a mercado reduce-only: asset: 0, isBuy: false, limitPx: 4800000000000 (peor precio), sz: 100000, reduceOnly: true, encodedTif: 0, triggerPx: 4900000000000, isMarket: true, tpsl: 2, cloid: 1760000000001.

HCPerpOrderBatch​

Hasta 100 órdenes bajo una misma agrupación, enviadas a POST /v1/tee-perp/orders/submit-batch. Cada orden debe usar un cloid distinto. grouping es 0 (sin agrupación), 1 (normalTpsl) o 2 (positionTpsl). Un lote cuenta como una sola colocación de orden frente al límite de tasa.

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. El array orders se codifica como keccak256 de los hashes concatenados de los structs PerpOrderTerms, en el orden de envío.

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x9d4f467a44f4b0d39f234f3b91888546ce31dcbb67ce791550901b9042c38f8b
Hash del array de órdenes0x13fc75fcc69bf3b4ef7cdc3a0872c3cc1cf59440c74d366055109b6bd5ea7c98
Hash del struct de la directiva0x69d0b1131e386769823fe1ab3facbe8e6fc013f86a117cf95cb52b8ce2f274e0
Digest a firmar0x4b5cd34b1f254fdd9881b7674a3412807e16cade1f2ccc7a1e261482682fbd07

El vector de prueba es grouping: 1 con dos órdenes: una compra límite GTC (limitPx: 5000000000000, sz: 100000, cloid: 1760000000000) seguida del stop-loss del ejemplo de trigger.

HCPerpLeverageChange​

Establece el apalancamiento de un activo, enviado a POST /v1/tee-perp/leverage/submit. leverage debe ser mayor que cero.

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

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xe13845f0e6c16a5e1fc56b2d11fb0972faa2ec30b01e94d58c72147fa9b6a463
Hash del struct de la acción0x0e6e271dd56192d7fb1f37ea2eaffecfbbe2d1f79cac78dce6a6930bb8cc253e
Hash del struct de la directiva0xe04b169bbb0e20042308e5aad1036ce60eda75f484a4d6093dc60f2c2231129e
Digest a firmar0xb2a43487152a7cecc73d2b6b84d817a58dd02c559b05289a8d8e1b5c3d25e266

El vector de prueba establece un apalancamiento cross de 5x en asset: 0.

HCPerpScheduleCancel​

El dead-man switch de Hyperliquid: cancela todas las órdenes abiertas en time (milisegundos Unix, al menos siete segundos en el futuro). Se envía a POST /v1/tee-perp/schedule-cancel/submit. Para eliminar una cancelación programada, omita time en la solicitud y firme time = 0. Enviar un 0 explícito se rechaza.

struct PerpScheduleCancel {
uint64 time;
}

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

Typehash: 0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xf21b6881e346bbf4b8d82e8ea507cf487e58dfc08776ad662591be7d6065bdfb
Hash del struct de la acción0x0a3ebfe48ef28a79beeee4d56e524f8a5280c38562efb697e7b1d63b3d475afc
Hash del struct de la directiva0xae64a13943a6a35b33aeb3095763b855c58c2119daf71e1e3228d8acf2645e8b
Digest a firmar0xa01806f47299010b5963a516562be3c3b44fed4f4a9e2e56c4bb601630146cdc

El vector de prueba programa una cancelación en time: 1760000060000.

Cancelación preparada firmada por el manager​

POST /v1/tee-perp/cancels/submit-prepared es la ruta de cancelación firmada por el manager. No usa un struct de datos tipados. El manager firma el digest de una cancelación nativa de Hyperliquid preparada, suministrada como preparedRequest (base64) con managerSignature en forma canónica low-s, junto con una authenticationSignature con marca de tiempo que autentica la wallet del manager. Consulte la Referencia de la API para el esquema de la solicitud.

Directivas del manager (HypercallManagerSign)​

Las firma el manager del Account. Use chain ID 999 y name HypercallManagerSign. El Account exige signer == manager. Envíelas con POST /v1/actions/{action}.

HCUpdateApiWallet​

Añade, reemplaza o elimina (addr = 0x0) la API wallet almacenada bajo name en el 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. Acción: versión 0, id 2. Envío: POST /v1/actions/hc_update_api_wallet con action igual a { "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);

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x8ebe7d19374200e5dc3ae838db74b370da95bd2b3a8aec9de85d2398dd4a9257
Hash del struct de la acción0x8b6c4a9db102e9d27c9a4069b39ba35e04948129359f0c15cd5103dd101ffce7
Hash del struct de la directiva0x830e291835ad182f290bc3d2bff09eaf9fd33acfbe44c6ad583218cd1a8232e5
Digest a firmar0x06589077544af449314db1fa8c7aac2d277cce9e833a04992d88161ede24cbe8

El vector de prueba usa name trading-bot (0x74726164696e672d626f74 rellenado con ceros a la derecha) y addr 0x2222222222222222222222222222222222222222. Consulte Onboarding para el flujo completo de API wallets. El Account emite ApiWalletUpdated(name, addr).

HLAddApiWallet​

Aprueba una API wallet de Hyperliquid para el Account en 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. Acción: versión 1, id 9. Envío: POST /v1/actions/hl_add_api_wallet.

apiWalletName es un string, por lo que su campo en el struct es keccak256(bytes(apiWalletName)). Ethers y viem lo hacen por usted.

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x71c0e0dfbddc3456015249946354324befde42b6851d1c9b26c6a29f2e0b1ac2
Hash del struct de la acción0xed32a441b0ee59c0252f5dff3411766289c9c35c19e3152b0b2b204176c2c7cd
Hash del struct de la directiva0xb990a3dfb4e8d96243539f8758b3a55249b217542bb4112f4f88ed67ec516ed9
Digest a firmar0x584886d020316085de0e0dec16331b8e990558be3e8fd004c47200abbebed518

El vector de prueba usa apiWalletAddress 0x2222222222222222222222222222222222222222 y apiWalletName hl-bot.

HLSendAsset​

Envía activos desde el Account en HyperCore a un destino.

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. Acción: versión 1, id 13. Envío: 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);

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595
Hash del struct de la acción0x9b8c0290da19ea1069e14833023c4621a4f043354b36b4f17d4803b1fce6e656
Hash del struct de la directiva0xa0cb8a72188a61289fc2685c29a424605e0a2ee7b7af3e8cfee10e1c75153e08
Digest a firmar0x7c7037f27c659a1885f744778480e6847c5d08e98fb22517265ba708b6597d10

El vector de prueba envía 5 USDC (amountWei: 500000000) desde perpetuos (srcDex: 0) a spot (dstDex: 4294967295), con destination igual al Exchange de producción 0xE6b7FaA216cabb2b38B392f577C9c826378b2240.

HLSetAbstraction​

Establece el modo de cuenta del Account en HyperCore. El Account solo acepta user igual a sí mismo y abstraction = 2 (cuenta unificada); cualquier otro valor revierte. Portfolio Margin lo requiere.

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. Acción: versión 1, id 16. Envío: POST /v1/actions/hl_set_abstraction.

Vector de prueba (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xcf5fddf081e5f2a9a45aa87cb1a3c42e5aa20164566b1ad2369b6b1318eac786
Hash del struct de la acción0xef6c70a3c14b9e77c710c6b3b3ee681ca270ef884bd8a64fa4064a96f3dda84e
Hash del struct de la directiva0xdda9d0fe82b63c728c4ac42585d5998a04cabaed0f957a2cafdf31a754829c3d
Digest a firmar0xf49d7d8d74596e503d6a1bdfb26653533a12a5ba3816acd992d0bd4ef378f59d

El vector de prueba establece user igual al Account y abstraction igual a 2.

HCTransferOption (reservado)​

Los contratos definen HCTransferOption(address account,uint64 nonce,TransferOption action)TransferOption(address recipient,address option,uint256 amountWei) (typehash 0xa218e1158788b23987f954edc7a07659a03a03fe5ba981a5bbe44d7a146e0819, versión de acción 0, id 1), pero no tiene asignado ningún tipo de firmante. El Account revierte con Account__UserDirectiveNotSupported, y la API rechaza hc_transfer_option. No lo firme. Mueva tokens de opciones con depositOption y retiros.

Transacciones del manager sin firma​

Algunas acciones del manager son llamadas directas al Account, no mensajes EIP-712: Account.approveZeroFeeBuilder(builder) aprueba un builder de Hyperliquid con una comisión máxima del 0% y se requiere una vez antes de la primera orden de perpetuos (consulte Onboarding). Account.transferTo(recipient, token, amount) mueve tokens fuera del Account en HyperEVM. Ambas requieren msg.sender == manager y revierten mientras el Account está en liquidación.

Directivas RSM (HypercallRsmSign)​

Las firma el firmante RSM y las envía el sequencer. Acreditan depósitos, procesan retiros, inician y detienen liquidaciones, y colocan órdenes de recuperación IOC reduce-only. Los market makers y usuarios no las firman ni las envían; se documentan para que usted pueda verificar lo que el protocolo puede hacer con un Account. Use chain ID 999 y name HypercallRsmSign. El Exchange verifica signer == rsmSigner (actualmente 0x502E7fAbF34E84EeB115C34FE947b79A94dF886E en mainnet) y quien llama debe tener SEQUENCER_ROLE.

Órdenes y barridos RSM (ejecutados por el Account)​

Reutilizan los structs HL bajo el dominio RSM, por lo que los typehashes son iguales a los de API y manager y solo cambia el separador de dominio. El Account aplica restricciones adicionales y las ejecuta incluso durante una liquidación.

MensajeTypehashRestricción aplicada por el Account
HLOrder0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707ddencodedTif debe ser IOC (3), y la orden debe ser reduceOnly, o una venta spot hacia USDC (ids de activo spot de 10000 a 99999) con límite no más de un 5% por debajo del precio spot de HyperCore
HLCancel0x23c5529f34a875b6c0d11a6dfafdd945996dbdc5fbd1bdace2c2e0cf6a253a85Ninguna
HLCancelByCloid0x10cbcfa56297fc737e4defee7b7937a52978ebbe5920e584317f7f25416836f5Ninguna
HLSendAsset0x7feffdf7e7b191d5d27c2a209ca71c789289da73de203e99546abf9632860595destination debe ser el Exchange

Vector de prueba de HLOrder RSM (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xe6facb816c5f9c321054ef43c7d8fb1ec750f65d630ec39c5c18119a6f4707dd
Hash del struct de la acción0x39b4e0699f382aaad23f04740034e7c5581ba918139d2db63fbf586cc447e7db
Hash del struct de la directiva0xe6dde5ad6d310b5ebb83c09ec28ee5568700473b885bb483b7437dca202af4f3
Digest a firmar0x57afa1e810804e768c05a467aa88ede15fdceedae5aaa840adff61a613aca469

El vector HLOrder RSM es una venta IOC reduce-only (isBuy: false, limitPx: 4800000000000, sz: 100000, reduceOnly: true, encodedTif: 3, cloid igual al nonce). Exchange.executeRsmDirective verifica la firma y reenvía la acción al Account.

Acciones de sistema (ejecutadas por el Exchange)​

Versión 255. Cada wrapper es System<Action>(address account,uint64 nonce,<Action> action)<Action>(...).

WrapperTipo internoTypehash
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

Cadenas completas de los tipos externos:

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 acredita tokens spot o de perpetuos desde HyperCore al Account. amountWei debe ser distinto de cero y el Account debe estar activado en HyperCore.
  • SystemCreditOption emite tokens de opciones al Account, desplegando el par de opciones si es necesario. underlying es una palabra ShortString de OpenZeppelin: ASCII alineado a la izquierda con la longitud en bytes en el último byte (BTC es 0x42544300...03). Las codificaciones no canónicas revierten.
  • SystemStartLiquidation registra los parámetros de la subasta y bloquea el Account. marginNeeded debe ser distinto de cero.
  • SystemStopLiquidation exige que startTime sea igual al inicio registrado y devuelve el Account a su manager.
  • SystemWithdrawToken pone en cola la entrega de USDC estándar en HyperCore desde el saldo propio del Exchange. Requiere subAccount = 0, srcDex = 0, dstDex igual a 0 o 4294967295, token = 0 (USDC) y un amountWei que sea múltiplo exacto de la unidad EVM. Un recibo de HyperEVM por sí solo no prueba la entrega en HyperCore.

Vector de prueba de SystemCreditToken (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xe845f2049264182802994dae939dc8ac42d3ae543a7eeb530dd021428743f052
Hash del struct de la acción0xc69d7c6e5c36c9789d990c6316eaff3be43980583806f41f8a8e6461b7114011
Hash del struct de la directiva0x7ffa37cef7e08d3a2dd5501a8648899d37bc09ebb25d148c124e12c5047476e1
Digest a firmar0x95f75e5ddb4837de3f578b8aa0d714d4b02672b18c4929e3d2dda4a266de8254

El vector acredita 5 USDC (srcDex y dstDex iguales a 4294967295, token: 0, amountWei: 500000000).

Vector de prueba de SystemCreditOption (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x65aedd5af06882e1e62d752b43b72ec62a85cacf2ca59e8ec2affc57eed9d8ae
Hash del struct de la acción0x4a8b563fc94d26c1da376145d5aa5d05f996232fcf9739ed0a662650e91861b6
Hash del struct de la directiva0x190b638f1a462469bf0d070248acfc86bbbb95ea8a9d3d97d33581c7d6bb5554
Digest a firmar0x86fb7c53bb7e139a4d5df7db2feae40e634efe09ea7509165d3cece75d75fce2

El vector acredita una opción call sobre BTC (underlying: 0x42544300...03, expiry: 1761811200, strike: 80000, isCall: true, amountWei: 1000000000000000000).

Vector de prueba de SystemStartLiquidation (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x92b6a135a656e489c24fb5511684842b0ab3895c22b51e4910dee90a7d23511e
Hash del struct de la acción0x4cd6a7f0997eba84ef82eabd429a0d9ca80e55bd6d89d2e67eda9970d87ec803
Hash del struct de la directiva0x84f18dc2577978d7890c9eb269fd787d99de37039b3a08e24745398feffbd0c5
Digest a firmar0xcc72c0e7829938c9ca0a4515d759f94cc96d2f24cd51a134a430f215ed5f5d4b

El vector usa equity: -1500000000 y marginNeeded: 20000000000 (ambos en USDC con seis decimales).

Vector de prueba de SystemStopLiquidation (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0xe1af98778e9cfd1d1a679bb0b64b6dc8aa3fb152ff6469d0a81a1c7eb87a4bd3
Hash del struct de la acción0x1d900a795b328bd5fa734bd6d7f74634b98ca66eb5e45322fb1ba6400564b62b
Hash del struct de la directiva0x977b9becdd26830f2cdf70ab40f72f24490fe6ed45822d1fc8c84120e9a46f40
Digest a firmar0xbe65f82782b14dba42e334e32dd7dcc6bf14c96824523723a186a7381f8f12af

El vector usa startTime: 1760000000.

Vector de prueba de SystemWithdrawToken (account 0x1111111111111111111111111111111111111111, nonce 1760000000000, cadena 999):

PasoValor
Typehash0x634b866e9a922bb846e297973c7a456e641b88f4e97493da9b222084d799c883
Hash del struct de la acción0x10bd8d4372a09e613a6b4fb7018fcccde857ebf6cc3327d6c9a3c0f81515a076
Hash del struct de la directiva0x86680427965513c65a7a170730b9f4fb2e2b40e22cd18338cb004b6a7872ada2
Digest a firmar0x65cc392038decb9ccdc23b0a4a1cfbe657d3417f8cd9ebf2319b3172fb7d885c

El vector retira 5 USDC (amountWei: 500000000) a destination 0x1111111111111111111111111111111111111111 con srcDex: 0, dstDex: 0, token: 0.

Nonces​

Cada firmante tiene un espacio de nonces independiente, registrado en tres lugares.

  • Contrato Account: un bitmap por firmante. Account.isNonceUsed(signer, nonce) indica si un nonce fue consumido. Una directiva de usuario revierte con Account__NonceAlreadyUsed si se reutiliza. No existe nextNonce; se permiten huecos y el orden no importa on-chain.
  • Contrato Exchange: un bitmap para el firmante RSM, consultable con Exchange.isNonceUsed(signer, nonce).
  • Motor: conserva los 100 nonces más altos por firmante. Un nuevo nonce no debe estar en el conjunto, debe superar el nonce más pequeño almacenado una vez que el conjunto está lleno, y debe estar estrictamente dentro de un rango de dos días antes y un día después de la hora del servidor en milisegundos.

Use la hora Unix actual en milisegundos como semilla del nonce e increméntela por firmante. Dos solicitudes firmadas por la misma wallet en el mismo milisegundo necesitan nonces distintos, así que mantenga un contador. En las rutas de perpetuos TEE el nonce también es el ancla temporal de la solicitud, por lo que allí debe usar marcas de tiempo reales en milisegundos y no enteros pequeños.

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

Flujo de verificación de firmas​

  1. Off-chain: el firmante construye el digest EIP-712 (0x1901 || domainSeparator || structHash) y lo firma.
  2. API: Hypercall recupera el firmante, verifica que sea una API wallet activa o el manager, ejecuta la verificación de margen del motor para las órdenes y luego pone la directiva en cola. La respuesta informa la etapa real, los detalles de rechazo y el hash de la transacción.
  3. Sequencer: envía Exchange.executeUserDirective(directive, signature). El Exchange verifica que el Account exista y reenvía a Account.executeUserDirective.
  4. Account: reconstruye el digest a partir de su propia dirección, el nonce y la acción, recupera el firmante con el separador de API o de manager correspondiente a esa acción, verifica la autorización, consume el nonce y luego ejecuta. Las acciones HL van al CoreWriter de HyperCore. Las acciones HC actualizan el registro de API wallets.
  5. Cliente: consulta GET /v1/directives/{directive_id} para obtener el estado final.

Las rutas de perpetuos TEE terminan después del paso de la API: es el enclave, no el Account, quien ejecuta la orden en 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

Obsoleto y eliminado​

Estos elementos aparecían en versiones anteriores de esta página y ya no forman parte del sistema desplegado. Se enumeran para que las integraciones construidas sobre ellos puedan migrarse.

  • Codificación de Processor y ActionCaster. El contrato Processor y la codificación de mensajes ActionCaster se eliminaron en Exchange 0.2.0 (febrero de 2026). Las directivas de Account ahora pasan por Exchange.executeUserDirective y CoreWriter. El Exchange 0.6.1 desplegado no tiene ninguno de los antiguos puntos de entrada.
  • Puntos de entrada del Exchange con structs propios. hlRequestOrder, hlRequestCancel, hlRequestCancelByCloid, hlActionSendAsset, hcActionWithdrawToken, hcActionWithdrawOption, rsmCommandRebalance y rsmCommandRepay ya no existen. Sus reemplazos:
Mensaje eliminadoReemplazo
HLRequestCancel (lote de HLCancel{asset,oid} más nonce)HLCancel con un CancelOrderByOid por directiva
HLRequestCancelByCloidHLCancelByCloid con un CancelOrderByCloid por directiva
HLActionSendAsset (account, nonce, destination, srcDex, dstDex, token, amountWei)HLSendAsset con SendAsset, que añade subAccount
HCActionWithdrawTokenSystemWithdrawToken firmado por RSM, ejecutado por el sequencer después de que el motor aprueba el retiro
HCActionWithdrawOptionLos créditos de opciones son SystemCreditOption de RSM; los depósitos usan depositOption
RsmCommandRebalanceHLOrder firmado por RSM (IOC reduce-only)
RsmCommandRepayHLSendAsset firmado por RSM hacia el Exchange
  • Funciones de órdenes heredadas. placeCoreOrders, cancelCoreOrders y cancelCoreOrdersByCloid usaban codificación MsgPack y el dominio CoreSignatures ("Exchange", chain ID 1337). Se han eliminado.
  • nextNonce. El contador on-chain nextNonce[signer] ya no existe. Solo queda el bitmap de nonces usados (isNonceUsed).
  • Separadores de mainnet marcados como TBD. El texto anterior listaba los separadores de mainnet de manager y RSM como TBD. Los tres están fijados y se listan arriba.
  • HCTransferOption. Definido pero nunca habilitado; consulte más arriba.

Consideraciones de seguridad​

  1. Claves: mantenga la clave del manager en una hardware wallet. Las API wallets solo firman órdenes y cancelaciones; use claves separadas para cada sistema.
  2. Reutilización de nonces: nunca reutilice un nonce. Registre los nonces off-chain e increméntelos de forma atómica.
  3. Dominio: firme siempre con chain ID 999 en mainnet (998 en testnet) y compare el separador que calcula con la tabla anterior.
  4. Verifique lo que firma: llame a POST /v1/actions/{action}/typed-data y compárelo con su propio codificador antes de firmar con una hardware wallet.
  5. La verificación on-chain es definitiva: la API verifica previamente las firmas, pero el Account vuelve a verificar cada directiva on-chain. No trate una confirmación de la API como ejecución.
  6. Manager frente a API wallet: los managers controlan la propiedad, las API wallets y el movimiento de activos. Las API wallets solo firman mensajes de trading. Use claves separadas.

Referencias​