Cette page a été traduite automatiquement. La version anglaise fait référence. Lire en anglais
Aller au contenu principal

Autorisation d'agent

Prise en charge de la signature multi-clés pour les teneurs de marché.

Vue d'ensemble

L'autorisation d'agent permet à une clé de signature dédiée (agent) de placer et d'annuler des ordres au nom d'un portefeuille de trading. Cela est utile pour :

  • Sécurité : conservez les clés du portefeuille de trading en stockage à froid et utilisez des clés « chaudes » pour la signature
  • Opérationnel : plusieurs membres d'une équipe peuvent signer avec des clés différentes
  • Automatisation : les systèmes automatisés peuvent signer avec des clés dédiées

Deux modèles d'autorisation

Hypercall dispose de deux systèmes de délégation distincts selon le produit :

ProduitType de délégationStockageMise en place
Options (API REST)Autorisation d'agentHors chaîne (base de données)POST /approve-agent
Perpétuels (directives on-chain)Portefeuille APISur la chaîne (contrat Exchange)Directive hc_update_api_wallet

Ce sont des systèmes indépendants. Approuver un agent pour le trading d'options ne l'autorise pas pour les perpétuels, et inversement.

Options : autorisation d'agent (hors chaîne)

Les agents signent les messages EIP-712 PlaceOrder et CancelOrder au nom d'un portefeuille de trading. Le serveur API vérifie l'autorisation dans sa base de données avant de transmettre au moteur.

Perpétuels : portefeuille API (on-chain)

Les portefeuilles API signent les directives des perpétuels en utilisant le domaine EIP-712 HypercallAgentSign. Le contrat Exchange vérifie l'autorisation sur la chaîne via isApiWalletActive(). Consultez Signature EIP-712 pour la référence complète de la signature des directives.

Pour ajouter ou supprimer un portefeuille API, soumettez une directive hc_update_api_wallet signée par le portefeuille gestionnaire du compte.

Cela reflète le modèle de portefeuille API de Hyperliquid. Hyperliquid documente ces portefeuilles API, aussi appelés portefeuilles d'agent, dans Nonces and API wallets, et documente approveAgent dans Exchange endpoint.

Protection contre le rejeu de nonce

Le suivi des nonces suit le modèle de nonce de Hyperliquid. Toutes les actions signées (ordres, approbation/révocation d'agent, handshakes QP) partagent un espace de nonces par signataire. Le moteur stocke les 100 nonces les plus élevés par adresse de signataire. Un nouveau nonce est accepté si :

  1. nonce > min(stored_set) -- il doit être supérieur au plus petit nonce stocké
  2. !stored_set.contains(nonce) -- il ne doit pas être un doublon
  3. nonce se situe dans l'intervalle (T - 2 jours, T + 1 jour) par rapport à l'horodatage du serveur

Les nonces hors séquence sont autorisés (par exemple, nonce 105 puis 102 fonctionnent tous deux si les deux sont supérieurs au minimum de l'ensemble). L'ensemble est limité à 100 entrées, donc les entrées les plus anciennes sont évincées à mesure que de nouvelles sont ajoutées. Cela empêche le blocage d'un compte à cause d'un seul nonce trop grand.

Le signataire du nonce est l'adresse qui a signé le message EIP-712 : le portefeuille API pour les ordres, le signataire récupéré pour l'autorisation d'agent, le portefeuille QP pour les handshakes. Les clients doivent utiliser Date.now() (epoch en millisecondes) comme graine de nonce et incrémenter de manière monotone.

Autorisation d'agent pour les options

Signature directe

Si signer == wallet, l'ordre est toujours autorisé (auto-signature).

Signature par agent

Si signer != wallet, le signataire doit être un agent autorisé :

  • L'agent doit être présent dans l'état d'autorisation détenu par le moteur
  • L'autorisation ne doit pas être expirée
  • Les snapshots du moteur et le journal du moteur sont les sources durables de restauration au redémarrage

Approuver un agent

Endpoint : POST /approve-agent

Requête : ApproveAgentRequest

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

Signature :

  • Le propriétaire du portefeuille signe le message ApproveAgent
  • Le portefeuille est dérivé de la signature récupérée
  • L'agent est le champ agent de la requête

Struct EIP-712 :

struct ApproveAgent {
address agent;
uint64 nonce;
}

Réponse : ApproveAgentResponse

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

Remarques :

  • L'autorisation d'agent est persistante (stockée en base de données)
  • L'autorisation n'expire pas sauf si expires_at est défini (pas encore implémenté)

Révoquer un agent

Endpoint : DELETE /revoke-agent

Requête : RevokeAgentRequest

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

Signature :

  • Le propriétaire du portefeuille signe le message RevokeAgent
  • Le portefeuille est dérivé de la signature récupérée

Struct EIP-712 :

struct RevokeAgent {
address agent;
uint64 nonce;
}

Réponse : RevokeAgentResponse

Remarques :

  • Applique une commande journalisée RevokeAgent à l'état d'autorisation détenu par le moteur
  • Les vérifications d'autorisation de l'API de trading lisent l'état du backend et appliquent les révocations pour les requêtes de trading. La publication dans la trollbox peut mettre en cache une autorisation d'agent positive plus longtemps, de sorte qu'un agent récemment révoqué pourrait encore pouvoir publier jusqu'à l'expiration de ce cache ou jusqu'à ce que l'invalidation au mieux atteigne la localisation périphérique concernée. Ce cache n'autorise pas les mutations de l'API de trading.
  • L'agent ne peut plus signer pour le portefeuille après révocation

Obtenir les agents autorisés

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

Paramètres de requête :

  • wallet (obligatoire)

Réponse :

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

Remarques :

  • Ne renvoie que les agents actifs et non expirés
  • Trié par created_at DESC

Utilisation des agents

Signer des ordres avec un agent

Une fois qu'un agent est approuvé :

  1. Signez l'ordre avec le portefeuille de l'agent : utilisez le portefeuille de l'agent pour signer les messages PlaceOrder / CancelOrder
  2. Définissez le champ wallet : définissez le champ wallet sur l'adresse du portefeuille de trading (et non l'adresse de l'agent)
  3. Vérification par le middleware : le middleware vérifie que l'agent est autorisé pour ce portefeuille

Exemple :

// 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
})
});

Ordres groupés avec un agent

Les endpoints groupés vérifient l'autorisation de l'agent élément par élément :

  • Chaque ordre dans POST /bulk_order peut être signé par un agent différent
  • L'autorisation de l'agent est vérifiée élément par élément
  • Si un élément échoue à l'autorisation d'agent, cet élément renvoie une erreur dans BulkOrderResult

Vérifications d'autorisation

Middleware (ordres individuels)

Endpoints :

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

Vérification : signature_and_agent_middleware vérifie :

  1. La récupération de la signature réussit
  2. Le signataire est autorisé (signer == wallet OU agent autorisé)

Handler (ordres groupés)

Endpoints :

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

Vérification : vérification par élément dans le handler :

  1. Récupération de la signature par élément
  2. Vérification de l'autorisation de l'agent par élément

Stockage des autorisations

L'autorisation d'agent est un état détenu par le moteur. Les commandes ApproveAgent et RevokeAgent sont journalisées, restaurées via le rejeu du moteur, et exposées via le snapshot de lecture pour les vérifications de l'API.

Logique d'autorisation

L'autorisation du signataire est une logique OU explicite :

  • Signature directe : signer == wallet.
  • Signature par agent : le snapshot du moteur contient un enregistrement d'autorisation pour wallet_address == <wallet> et agent_address == <signer>, et expires_at est absent ou dans le futur.

Expiration

expires_at est appliqué par les vérifications d'autorisation du snapshot du moteur. Les agents avec expires_at < NOW() sont traités comme non autorisés.

Considérations de sécurité

  1. Sécurité des clés d'agent : protégez les clés privées des agents (utilisez des portefeuilles matériels ou une gestion sécurisée des clés)
  2. Audits réguliers : examinez régulièrement les agents autorisés via GET /authorized-agents
  3. Révoquez les agents inutilisés : révoquez les agents qui ne sont plus nécessaires
  4. Expiration : utilisez expires_at pour les autorisations d'agent temporaires lorsque le chemin d'approbation expose une expiration non définie par défaut

Bonnes pratiques

  1. Utilisez des agents pour l'automatisation : conservez les clés du portefeuille de trading en stockage à froid, utilisez des agents pour les systèmes automatisés
  2. Limitez la portée des agents : n'approuvez que les agents qui ont besoin d'un accès
  3. Surveillez l'utilisation des agents : suivez quels agents placent des ordres
  4. Révoquez rapidement : révoquez immédiatement les agents qui ne sont plus nécessaires

Problèmes courants

« Unauthorized: signer not authorized for wallet »

Cause : l'agent n'est pas approuvé ou l'autorisation a expiré/a été révoquée.

Solution : approuvez l'agent via POST /approve-agent ou signez directement avec le portefeuille.

L'autorisation d'agent ne fonctionne pas

Causes :

  • L'agent n'est pas présent dans l'état d'autorisation détenu par le moteur
  • L'autorisation a été révoquée
  • L'autorisation a expiré

Solution : vérifiez le statut de l'agent via GET /authorized-agents?wallet=....