Esta página foi traduzida automaticamente. O original em inglês é a versão canônica. Ler em inglês
Pular para o conteúdo principal

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:

ProdutoTipo de DelegaçãoArmazenamentoComo Configurar
Opções (API REST)Autorização de agenteOff-chain (banco de dados)POST /approve-agent
Perpétuos (diretivas on-chain)Carteira de APIOn-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:

  1. nonce > min(stored_set) -- deve ser maior que o menor nonce armazenado
  2. !stored_set.contains(nonce) -- não deve ser duplicado
  3. nonce está 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 agent na 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_at seja 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 RevokeAgent registrado 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:

  1. Assine a ordem com a carteira do agente: Use a carteira do agente para assinar mensagens PlaceOrder / CancelOrder
  2. Defina o campo wallet: Defina o campo wallet com o endereço da carteira de negociação (não o endereço do agente)
  3. 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_order pode 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 /order
  • DELETE /order
  • DELETE /order_cloid

Verificação: signature_and_agent_middleware verifica:

  1. A recuperação da assinatura é bem-sucedida
  2. O assinante está autorizado (signer == wallet OU agente autorizado)

Handler (Ordens em Lote)

Endpoints:

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

Verificação: Verificação por item no handler:

  1. Recuperação de assinatura por item
  2. 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> e agent_address == <signer>, e expires_at está 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

  1. Segurança da chave do agente: Proteja as chaves privadas do agente (use hardware wallets ou gerenciamento seguro de chaves)
  2. Auditorias regulares: Revise os agentes autorizados via GET /authorized-agents regularmente
  3. Revogue agentes não utilizados: Revogue agentes que não são mais necessários
  4. Expiração: Use expires_at para autorizações temporárias de agente quando o fluxo de aprovação expuser um vencimento diferente do padrão

Boas Práticas

  1. Use agentes para automação: Mantenha as chaves da carteira de negociação em cold storage e use agentes para sistemas automatizados
  2. Limite o escopo dos agentes: Aprove apenas agentes que precisam de acesso
  3. Monitore o uso dos agentes: Acompanhe quais agentes estão colocando ordens
  4. 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=....