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 Agentes

Suporte a assinatura com múltiplas chaves para market makers.

Visão geral​

A autorização de agentes permite que uma chave de assinatura dedicada (agente) envie 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 armazenamento a frio e use chaves quentes 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 tem dois sistemas de delegação separados, dependendo do produto:

ProdutoTipo de delegaçãoArmazenamentoComo configurar
Opções (REST API)Autorização de agenteEstado do engine da HypercallPOST /approve-agent
PerpétuosCarteira de APIOn-chain (seu contrato Account)Diretiva hc_update_api_wallet

Esses sistemas são independentes. Aprovar um agente para negociar 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. A API verifica o agente no estado de autorização do engine antes que a ordem chegue ao engine.

Perpétuos: carteira de API (on-chain)​

As carteiras de API assinam ordens e cancelamentos de perpétuos no domínio EIP-712 HypercallApiSign. A Hypercall verifica o signatário no seu contrato Account (isApiWalletActive()) antes de admitir a ordem. Na rota TEE (o padrão do app, e opcional para clientes de API), um enclave seguro que guarda uma chave de negociação separada da Hyperliquid para a sua Account assina e envia a ordem nativa. Na rota de smart contract, uma configuração avançada no app, a ordem passa pelo seu contrato Account. Consulte Assinatura EIP-712 para a referência de assinatura e Perpétuos para o fluxo.

Para adicionar ou remover uma carteira de API, envie uma diretiva hc_update_api_wallet assinada pela carteira gestora da conta.

Isso espelha o modelo de carteiras 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 agentes, handshakes de QP) compartilham um espaço de nonces por signatário. O engine armazena os 100 maiores nonces por endereço signatário. Um novo nonce é aceito se:

  1. !stored_set.contains(nonce): não é duplicado
  2. nonce > min(stored_set) quando o conjunto tem 100 entradas: é maior que o menor nonce armazenado
  3. nonce está dentro de (T - 2 dias, T + 1 dia) em relação ao timestamp do servidor

Nonces fora de ordem são permitidos (por exemplo, o nonce 105 e depois o 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 à medida que novas são adicionadas. Isso evita que uma conta fique inutilizável por causa de um único nonce muito alto.

O signatário do nonce é o endereço que assinou a mensagem EIP-712: a carteira de API para ordens, o signatário recuperado para autorização de agentes e a carteira do QP para handshakes. Os clientes devem usar Date.now() (epoch em milissegundos) como semente do nonce e incrementá-lo de forma monotônica.

Autorização de agentes para opções​

Assinatura direta​

Se signer == wallet, a ordem é sempre autorizada (autoassinatura).

Assinatura por agente​

Se signer != wallet, o signatário precisa ser um agente autorizado:

  • O agente precisa 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 dono 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 é estado do engine registrado no journal e sobrevive a reinicializações
  • Aprovações feitas por este endpoint não expiram

Revogar agente​

Endpoint: DELETE /revoke-agent

Requisição: RevokeAgentRequest

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

Assinatura:

  • O dono 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 as revogações às requisições de negociação. A publicação no Trollbox pode manter em cache a autorização positiva do agente por mais tempo, então um agente revogado recentemente ainda pode conseguir publicar até que esse cache expire ou que a invalidação best-effort chegue ao edge location relevante. Esse cache não autoriza mutações na API de negociação.
  • Após a revogação, o agente não pode mais assinar pela carteira

Revogar todos os agentes​

Endpoint: DELETE /revoke-all-agents

Requisição: { "nonce": 3, "signature": "0x..." }, assinada pelo dono da carteira sobre RevokeAllAgents(uint64 nonce). Remove todos os agentes da carteira recuperada.

Consultar 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

Uso de agentes​

Assinando ordens com um agente​

Depois 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 no 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. The REST body uses snake_case `client_id`.
const { clientId, ...rest } = message;
const response = await fetch('/order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...rest,
client_id: clientId,
signature
})
});

Ordens em lote com um agente​

Os endpoints em lote verificam a autorização de agente item a item:

  • Cada ordem em POST /bulk_order pode ser assinada por um agente diferente
  • A autorização de agente é verificada item a item
  • Se algum item falhar na autorização de 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 signatário 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 item a item no handler:

  1. Recuperação da assinatura por item
  2. Verificação de autorização de agente por item

Armazenamento da autorização​

A autorização de agentes é estado mantido pelo engine. Os comandos ApproveAgent e RevokeAgent são registrados no journal, restaurados pelo replay do engine e expostos pelo snapshot de leitura para as verificações da API.

Lógica de autorização​

A autorização do signatário é uma lógica OU 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​

O engine aceita um expires_at em uma autorização e trata um agente expirado como não autorizado. POST /approve-agent não define esse campo, então os agentes aprovados pela API permanecem ativos até serem revogados.

Considerações de segurança​

  1. Segurança da chave do agente: proteja as chaves privadas dos agentes (use hardware wallets ou um gerenciamento de chaves seguro)
  2. Auditorias regulares: revise regularmente os agentes autorizados via GET /authorized-agents
  3. Revogue agentes sem uso: revogue os agentes que não são mais necessários

Boas práticas​

  1. Use agentes para automação: mantenha as chaves da carteira de negociação em armazenamento a frio e use agentes para sistemas automatizados
  2. Limite o escopo dos agentes: aprove apenas os agentes que precisam de acesso
  3. Monitore o uso dos agentes: acompanhe quais agentes estão enviando ordens
  4. Revogue rapidamente: revogue os agentes imediatamente quando não forem mais necessários

Problemas comuns​

"Signer 0x... is not authorized to act for wallet 0x..."​

Causa: o agente não foi aprovado ou a autorização expirou ou foi revogada.

Solução: aprove o agente via POST /approve-agent ou assine diretamente com a carteira.

A autorização de agente não está funcionando​

Causas:

  • O 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=....