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

Autorización de Agentes

Soporte de firma multi-clave para market makers.

Descripción General

La autorización de agentes permite que una clave de firma dedicada (agente) coloque y cancele órdenes en nombre de una wallet de trading. Esto es útil para:

  • Seguridad: Mantenga las claves de la wallet de trading en almacenamiento en frío y use claves calientes para firmar
  • Operaciones: Varios miembros del equipo pueden firmar con claves diferentes
  • Automatización: Los sistemas automatizados pueden firmar con claves dedicadas

Dos Modelos de Autorización

Hypercall tiene dos sistemas de delegación separados según el producto:

ProductoTipo de DelegaciónAlmacenamientoCómo Configurarlo
Opciones (API REST)Autorización de agenteOff-chain (base de datos)POST /approve-agent
Perpetuos (directivas on-chain)API walletOn-chain (contrato Exchange)Directiva hc_update_api_wallet

Estos son sistemas independientes. Aprobar un agente para el trading de opciones no lo autoriza para perpetuos, y viceversa.

Opciones: Autorización de Agente (Off-Chain)

Los agentes firman mensajes EIP-712 de PlaceOrder y CancelOrder en nombre de una wallet de trading. El servidor de la API verifica la autorización contra su base de datos antes de reenviarla al motor.

Perpetuos: API Wallet (On-Chain)

Las API wallets firman directivas de perpetuos usando el dominio EIP-712 HypercallAgentSign. El contrato Exchange verifica la autorización on-chain mediante isApiWalletActive(). Consulte Firma EIP-712 para la referencia completa de firma de directivas.

Para agregar o eliminar una API wallet, envíe una directiva hc_update_api_wallet firmada por la wallet administradora de la cuenta.

Esto refleja el modelo de API wallets de Hyperliquid. Hyperliquid las documenta como API wallets, también llamadas agent wallets, en Nonces and API wallets, y documenta approveAgent en el Exchange endpoint.

Protección contra Repetición de Nonces

El seguimiento de nonces sigue el modelo de nonces de Hyperliquid. Todas las acciones firmadas (órdenes, aprobación/revocación de agentes, handshakes de QP) comparten un espacio de nonces por firmante. El motor almacena los 100 nonces más altos por dirección de firmante. Un nuevo nonce se acepta si:

  1. nonce > min(stored_set) -- debe ser mayor que el nonce almacenado más pequeño
  2. !stored_set.contains(nonce) -- no debe ser un duplicado
  3. nonce está dentro de (T - 2 días, T + 1 día) respecto al timestamp del servidor

Se permiten nonces fuera de orden (p. ej., nonce 105 y luego 102 funcionan ambos si ambos están por encima del mínimo del conjunto). El conjunto está limitado a 100 entradas, por lo que las entradas más antiguas se eliminan a medida que se agregan nuevas. Esto evita que la cuenta quede inutilizada por un único nonce grande.

El firmante del nonce es la dirección que firmó el mensaje EIP-712: la API wallet para órdenes, el firmante recuperado para la autorización de agentes, la wallet QP para handshakes. Los clientes deben usar Date.now() (época en milisegundos) como semilla del nonce e incrementarla de forma monotónica.

Autorización de Agentes para Opciones

Firma Directa

Si signer == wallet, la orden siempre está autorizada (auto-firma).

Firma por Agente

Si signer != wallet, el firmante debe ser un agente autorizado:

  • El agente debe estar presente en el estado de autorización propiedad del motor
  • La autorización no debe haber expirado
  • Los snapshots del motor y el journal del motor son las fuentes duraderas para el reinicio

Aprobar Agente

Endpoint: POST /approve-agent

Solicitud: ApproveAgentRequest

{
"agent": "0x...",
"nonce": 1,
"signature": "0x..."
}

Firma:

  • El propietario de la wallet firma el mensaje ApproveAgent
  • La wallet se deriva de la firma recuperada
  • El agente es el campo agent en la solicitud

Struct EIP-712:

struct ApproveAgent {
address agent;
uint64 nonce;
}

Respuesta: ApproveAgentResponse

{
"success": true,
"error": null
}

Notas:

  • La autorización de agentes es persistente (almacenada en la base de datos)
  • La autorización no expira a menos que se establezca expires_at (aún no implementado)

Revocar Agente

Endpoint: DELETE /revoke-agent

Solicitud: RevokeAgentRequest

{
"agent": "0x...",
"nonce": 2,
"signature": "0x..."
}

Firma:

  • El propietario de la wallet firma el mensaje RevokeAgent
  • La wallet se deriva de la firma recuperada

Struct EIP-712:

struct RevokeAgent {
address agent;
uint64 nonce;
}

Respuesta: RevokeAgentResponse

Notas:

  • Aplica un comando RevokeAgent registrado en el journal al estado de autorización propiedad del motor
  • Las verificaciones de autorización de la API de trading leen el estado del backend y aplican las revocaciones para las solicitudes de trading. La publicación en el Trollbox puede almacenar en caché la autorización positiva de un agente durante más tiempo, por lo que un agente recientemente revocado aún podría publicar hasta que esa caché expire o la invalidación de mejor esfuerzo alcance la ubicación de borde correspondiente. Esta caché no autoriza mutaciones de la API de trading.
  • El agente ya no puede firmar por la wallet después de la revocación

Obtener Agentes Autorizados

Endpoint: GET /authorized-agents?wallet=...

Parámetros de consulta:

  • wallet (requerido)

Respuesta:

{
"agents": [
"0x...",
"0x..."
]
}

Notas:

  • Devuelve solo agentes activos y no expirados
  • Ordenados por created_at DESC

Uso de Agentes

Firmar Órdenes con un Agente

Una vez que un agente está aprobado:

  1. Firme la orden con la wallet del agente: Use la wallet del agente para firmar los mensajes PlaceOrder / CancelOrder
  2. Configure el campo wallet: Establezca el campo wallet con la dirección de la wallet de trading (no la dirección del agente)
  3. Verificación del middleware: El middleware verifica que el agente esté autorizado para esa wallet

Ejemplo:

// Agent wallet signs the order
const agentSigner = new ethers.Wallet(agentPrivateKey);

const message = {
wallet: "0x...", // Trading wallet (not agent)
symbol: "BTC-20250131-100000-C",
side: "Buy",
size: "0.1",
price: "100.0",
tif: "gtc",
clientId: "mm-1",
nonce: 1
};

// Sign with agent wallet
const signature = await agentSigner._signTypedData(domain, types, message);

// Send request
const response = await fetch('/order', {
method: 'POST',
body: JSON.stringify({
...message,
signature
})
});

Órdenes en Bloque con un Agente

Los endpoints en bloque verifican la autorización del agente por cada ítem:

  • Cada orden en POST /bulk_order puede estar firmada por un agente diferente
  • La autorización del agente se verifica por ítem
  • Si algún ítem falla la autorización del agente, ese ítem devuelve un error en BulkOrderResult

Verificaciones de Autorización

Middleware (Órdenes Individuales)

Endpoints:

  • POST /order
  • DELETE /order
  • DELETE /order_cloid

Verificación: signature_and_agent_middleware verifica que:

  1. La recuperación de la firma sea exitosa
  2. El firmante esté autorizado (signer == wallet O agente autorizado)

Handler (Órdenes en Bloque)

Endpoints:

  • POST /bulk_order
  • DELETE /bulk_order
  • DELETE /bulk_order_cloid

Verificación: Verificación por ítem en el handler:

  1. Recuperación de la firma por ítem
  2. Verificación de autorización del agente por ítem

Almacenamiento de la Autorización

La autorización de agentes es un estado propiedad del motor. Los comandos ApproveAgent y RevokeAgent se registran en el journal, se restauran mediante la reproducción del motor y se exponen a través del snapshot de lectura para las verificaciones de la API.

Lógica de Autorización

La autorización del firmante es una lógica OR explícita:

  • Firma directa: signer == wallet.
  • Firma por agente: el snapshot del motor contiene un registro de autorización para wallet_address == <wallet> y agent_address == <signer>, y expires_at está ausente o en el futuro.

Expiración

expires_at se aplica mediante las verificaciones de autorización del snapshot del motor. Los agentes con expires_at < NOW() se consideran no autorizados.

Consideraciones de Seguridad

  1. Seguridad de las claves del agente: Proteja las claves privadas del agente (use hardware wallets o gestión segura de claves)
  2. Auditorías regulares: Revise regularmente los agentes autorizados mediante GET /authorized-agents
  3. Revoque agentes sin uso: Revoque los agentes que ya no sean necesarios
  4. Expiración: Use expires_at para autorizaciones temporales de agentes cuando la ruta de aprobación exponga un vencimiento no predeterminado

Mejores Prácticas

  1. Use agentes para la automatización: Mantenga las claves de la wallet de trading en almacenamiento en frío y use agentes para los sistemas automatizados
  2. Limite el alcance de los agentes: Apruebe solo los agentes que necesiten acceso
  3. Monitoree el uso de agentes: Haga seguimiento de qué agentes están colocando órdenes
  4. Revoque con prontitud: Revoque los agentes inmediatamente cuando ya no sean necesarios

Problemas Comunes

"Unauthorized: signer not authorized for wallet"

Causa: El agente no está aprobado o la autorización expiró o fue revocada.

Solución: Apruebe el agente mediante POST /approve-agent o firme directamente con la wallet.

La Autorización del Agente No Funciona

Causas:

  • El agente no está presente en el estado de autorización propiedad del motor
  • La autorización fue revocada
  • La autorización ha expirado

Solución: Verifique el estado del agente mediante GET /authorized-agents?wallet=....