Autorização de Agente
Suporte a assinatura multi-chave para market makers.
Visão Geral
A autorização de agente permite que uma chave de assinatura dedicada (agente) coloque e cancele ordens em nome de uma carteira de negociação. Isso é útil para:
- Segurança: Mantenha as chaves da carteira de negociação em cold storage e use hot keys para assinar
- Operacional: Vários membros da equipe podem assinar com chaves diferentes
- Automação: Sistemas automatizados podem assinar com chaves dedicadas
Dois Modelos de Autorização
A Hypercall possui dois sistemas de delegação separados, dependendo do produto:
| Produto | Tipo de Delegação | Armazenamento | Como Configurar |
|---|---|---|---|
| Opções (API REST) | Autorização de agente | Off-chain (banco de dados) | POST /approve-agent |
| Perpétuos (diretivas on-chain) | Carteira de API | On-chain (contrato Exchange) | Diretiva hc_update_api_wallet |
Esses são sistemas independentes. Aprovar um agente para negociação de opções não o autoriza para perpétuos, e vice-versa.
Opções: Autorização de Agente (Off-Chain)
Os agentes assinam mensagens EIP-712 PlaceOrder e CancelOrder em nome de uma carteira de negociação. O servidor da API verifica a autorização em seu banco de dados antes de encaminhar para o engine.
Perpétuos: Carteira de API (On-Chain)
Carteiras de API assinam diretivas de perpétuos usando o domínio EIP-712 HypercallAgentSign. O contrato Exchange verifica a autorização on-chain via isApiWalletActive(). Consulte Assinatura EIP-712 para a referência completa de assinatura de diretivas.
Para adicionar ou remover uma carteira de API, envie uma diretiva hc_update_api_wallet assinada pela carteira gerenciadora da conta.
Isso espelha o modelo de carteira de API da Hyperliquid. A Hyperliquid documenta essas carteiras como carteiras de API, também chamadas de carteiras de agente, em Nonces and API wallets, e documenta approveAgent no Exchange endpoint.
Proteção Contra Replay de Nonce
O rastreamento de nonces segue o modelo de nonce da Hyperliquid. Todas as ações assinadas (ordens, aprovação/revogação de agente, handshakes de QP) compartilham um espaço de nonce por assinante. O engine armazena os 100 nonces mais altos por endereço de assinante. Um novo nonce é aceito se:
nonce > min(stored_set)-- deve ser maior que o menor nonce armazenado!stored_set.contains(nonce)-- não deve ser duplicadononceestá dentro de (T - 2 dias, T + 1 dia) do timestamp do servidor
Nonces fora de ordem são permitidos (por exemplo, nonce 105 e depois 102 funcionam se ambos estiverem acima do mínimo do conjunto). O conjunto é limitado a 100 entradas, então as entradas mais antigas são removidas conforme novas são adicionadas. Isso evita que a conta seja inutilizada por um único nonce muito grande.
O assinante do nonce é o endereço que assinou a mensagem EIP-712: a carteira de API para ordens, o assinante recuperado para autorização de agente, a carteira QP para handshakes. Os clientes devem usar Date.now() (epoch em milissegundos) como seed do nonce e incrementar monotonicamente.
Autorização de Agente para Opções
Assinatura Direta
Se signer == wallet, a ordem é sempre autorizada (auto-assinatura).
Assinatura por Agente
Se signer != wallet, o assinante deve ser um agente autorizado:
- O agente deve estar presente no estado de autorização mantido pelo engine
- A autorização não pode estar expirada
- Os snapshots do engine e o journal do engine são as fontes duráveis para reinicialização
Aprovar Agente
Endpoint: POST /approve-agent
Requisição: ApproveAgentRequest
{
"agent": "0x...",
"nonce": 1,
"signature": "0x..."
}
Assinatura:
- O proprietário da carteira assina a mensagem
ApproveAgent - A carteira é derivada da assinatura recuperada
- O agente é o campo
agentna requisição
Struct EIP-712:
struct ApproveAgent {
address agent;
uint64 nonce;
}
Resposta: ApproveAgentResponse
{
"success": true,
"error": null
}
Observações:
- A autorização de agente é persistente (armazenada no banco de dados)
- A autorização não expira, a menos que
expires_atseja definido (ainda não implementado)
Revogar Agente
Endpoint: DELETE /revoke-agent
Requisição: RevokeAgentRequest
{
"agent": "0x...",
"nonce": 2,
"signature": "0x..."
}
Assinatura:
- O proprietário da carteira assina a mensagem
RevokeAgent - A carteira é derivada da assinatura recuperada
Struct EIP-712:
struct RevokeAgent {
address agent;
uint64 nonce;
}
Resposta: RevokeAgentResponse
Observações:
- Aplica um comando
RevokeAgentregistrado no journal ao estado de autorização mantido pelo engine - As verificações de autorização da API de negociação leem o estado do backend e aplicam revogações para requisições de negociação. A publicação no Trollbox pode manter em cache uma autorização positiva de agente por mais tempo, então um agente recém-revogado ainda pode conseguir postar até que esse cache expire ou a invalidação best-effort alcance o edge location relevante. Esse cache não autoriza mutações na API de negociação.
- O agente não pode mais assinar pela carteira após a revogação
Obter Agentes Autorizados
Endpoint: GET /authorized-agents?wallet=...
Parâmetros de consulta:
wallet(obrigatório)
Resposta:
{
"agents": [
"0x...",
"0x..."
]
}
Observações:
- Retorna apenas agentes ativos e não expirados
- Ordenado por
created_at DESC
Uso do Agente
Assinando Ordens com Agente
Uma vez que um agente é aprovado:
- Assine a ordem com a carteira do agente: Use a carteira do agente para assinar mensagens
PlaceOrder/CancelOrder - Defina o campo wallet: Defina o campo
walletcom o endereço da carteira de negociação (não o endereço do agente) - Verificação pelo middleware: O middleware verifica se o agente está autorizado para essa carteira
Exemplo:
// 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
})
});
Ordens em Lote com Agente
Os endpoints de lote verificam a autorização do agente por item:
- Cada ordem em
POST /bulk_orderpode ser assinada por um agente diferente - A autorização do agente é verificada por item
- Se algum item falhar na autenticação do agente, esse item retorna erro em
BulkOrderResult
Verificações de Autorização
Middleware (Ordens Individuais)
Endpoints:
POST /orderDELETE /orderDELETE /order_cloid
Verificação: signature_and_agent_middleware verifica:
- A recuperação da assinatura é bem-sucedida
- O assinante está autorizado (signer == wallet OU agente autorizado)
Handler (Ordens em Lote)
Endpoints:
POST /bulk_orderDELETE /bulk_orderDELETE /bulk_order_cloid
Verificação: Verificação por item no handler:
- Recuperação de assinatura por item
- Verificação de autorização de agente por item
Armazenamento de Autorização
A autorização de agente é um estado mantido pelo engine. Os comandos ApproveAgent e RevokeAgent são registrados no journal, restaurados por meio do replay do engine e expostos pelo snapshot de leitura para as verificações da API.
Lógica de Autorização
A autorização do assinante é uma lógica OR explícita:
- Assinatura direta:
signer == wallet. - Assinatura por agente: o snapshot do engine contém um registro de autorização para
wallet_address == <wallet>eagent_address == <signer>, eexpires_atestá ausente ou no futuro.
Expiração
expires_at é aplicado pelas verificações de autorização do snapshot do engine. Agentes com
expires_at < NOW() são tratados como não autorizados.
Considerações de Segurança
- Segurança da chave do agente: Proteja as chaves privadas do agente (use hardware wallets ou gerenciamento seguro de chaves)
- Auditorias regulares: Revise os agentes autorizados via
GET /authorized-agentsregularmente - Revogue agentes não utilizados: Revogue agentes que não são mais necessários
- Expiração: Use
expires_atpara autorizações temporárias de agente quando o fluxo de aprovação expuser um vencimento diferente do padrão
Boas Práticas
- Use agentes para automação: Mantenha as chaves da carteira de negociação em cold storage e use agentes para sistemas automatizados
- Limite o escopo dos agentes: Aprove apenas agentes que precisam de acesso
- Monitore o uso dos agentes: Acompanhe quais agentes estão colocando ordens
- Revogue prontamente: Revogue agentes imediatamente quando não forem mais necessários
Problemas Comuns
"Unauthorized: signer not authorized for wallet"
Causa: Agente não aprovado ou autorização expirada/revogada.
Solução: Aprove o agente via POST /approve-agent ou assine diretamente com a carteira.
Autorização de Agente Não Funciona
Causas:
- Agente não está presente no estado de autorização mantido pelo engine
- A autorização foi revogada
- A autorização está expirada
Solução: Verifique o status do agente via GET /authorized-agents?wallet=....