Onboarding
Ce document décrit le cycle de vie du compte on-chain, les flux de financement et la gestion des portefeuilles API pour les teneurs de marché.
Vue d'ensemble
Hypercall utilise un modèle manager/agent :
- Manager : l'EOA qui détient le compte (généralement votre portefeuille principal)
- Compte : un contrat proxy minimal (clone) qui détient les fonds et exécute les actions on-chain
- Portefeuille API : un EOA autorisé par le manager à signer les requêtes de trading (agent)
Toutes les interactions on-chain s'effectuent via le contrat Exchange.
Adresses des contrats
Testnet
- Exchange : ``
Réseau principal
- Les détails sont communiqués en privé.
Cycle de vie du compte
1. Vérifier les comptes existants
Avant de créer un nouveau compte, vérifiez si vous possédez déjà des comptes :
function getAccounts(address manager) external view returns (ManagedAccount[] memory);
Exemple (ethers.js) :
const exchange = new ethers.Contract(EXCHANGE_ADDRESS, EXCHANGE_ABI, provider);
const accounts = await exchange.getAccounts(managerAddress);
// Returns: [{ account: "0x...", manager: "0x...", apiWallets: ["0x..."] }]
2. Créer un compte
Crée un nouveau compte avec msg.sender comme manager :
function createAccount() external payable returns (address account);
Exigences :
accountImpldoit être défini par la gouvernancemsg.value >= getCreationDeposit()(dépôt minimum en HYPE)- Si
creationDepositUsd == 0, aucun dépôt minimum n'est requis - Sinon,
getCreationDeposit()convertit le montant en USD en HYPE au prix spot actuel
- Si
Comportement :
- Déploie un proxy minimal déterministe (clone) de
accountImpl - Définit
msg.sendercomme manager du compte - Si
msg.value > 0, effectue un dépôt en HYPE pour le compte- Transfère les HYPE vers
HYPE_SYSTEM_ADDRESS(pont HyperCore) - Si le dépôt est >= 1 $ en HYPE, le compte est activé sur HyperCore (frais d'activation déduits)
- Transfère les HYPE vers
Exemple (ethers.js) :
// Get minimum deposit (in HYPE wei)
const minDeposit = await exchange.getCreationDeposit();
// Or set to ~$1-2 worth of HYPE for activation
const depositAmount = ethers.parseEther("0.001"); // Adjust based on HYPE price
const tx = await exchange.createAccount({ value: depositAmount });
const receipt = await tx.wait();
// Account address is deterministic - can predict before creation
Prédire l'adresse du compte :
function predictNextAccount(address manager) external view returns (address);
Utilisez cette fonction pour connaître l'adresse du compte avant sa création (utile pour l'UI/UX).
3. Transfert de compte
Les managers peuvent transférer la propriété d'un compte (pas directement appelable ; se produit lors de la création ou via la gouvernance) :
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
La fonctionnalité de transfert de compte est fournie sur demande.
Gestion des portefeuilles API
Les portefeuilles API sont des EOA autorisés par le manager à signer les requêtes de trading. Ils signent des messages EIP-712 qui sont vérifiés on-chain.
Ajouter un portefeuille API
function addApiWallet(address account, address apiWallet) external;
Exigences :
msg.sender == managers[account](doit être le manager du compte)apiWalletne doit pas être actif pour un autre compte/manageraccount != address(0)etapiWallet != address(0)
Comportement :
- Associe
apiWallet -> accountetapiWallet -> manager - Ajoute
apiWalletà l'ensemble des portefeuilles API du compte - Émet
ApiWalletAdded(account, manager, apiWallet)
Exemple :
const tx = await exchange.addApiWallet(accountAddress, apiWalletAddress);
await tx.wait();
Retirer un portefeuille API
function removeApiWallet(address account, address apiWallet) external;
Exigences :
msg.sender == managers[account]apiWalletdoit être actif pour ce compte/manager
Comportement :
- Supprime les associations pour
apiWallet - Retire
apiWalletde l'ensemble des portefeuilles API du compte - Émet
ApiWalletRemoved(account, manager, apiWallet)
Interroger les portefeuilles API
function getAccountByApiWallet(address apiWallet) external view returns (ManagedAccount memory);
Retourne le compte, le manager et tous les portefeuilles API du compte si apiWallet est actif. Retourne une structure nulle s'il est inactif.
Exemple :
const managedAccount = await exchange.getAccountByApiWallet(apiWalletAddress);
if (managedAccount.account !== ethers.ZeroAddress) {
console.log("Account:", managedAccount.account);
console.log("Manager:", managedAccount.manager);
console.log("API Wallets:", managedAccount.apiWallets);
}
Financement et dépôts
Dépôt USDC vers Hypercall
function depositUsdcFor(address account, uint256 amount) external;
depositUsdcFor est la voie de financement directe HyperEVM pour les soldes en espèces Hypercall. Elle transfère des USDC natifs HyperEVM de msg.sender vers Exchange, puis Exchange dépose ces USDC dans son solde HyperCore via le CoreDepositWallet de Circle.
Qui peut l'appeler :
- Tout portefeuille, routeur, solveur ou contrat zap peut appeler cette méthode.
msg.senderpaie les USDC.accountest le compte ou portefeuille Hypercall à créditer. Ne déduisez pas le compte crédité demsg.sender.
Exigences :
account != address(0)amount > 0msg.senderdoit approuverExchangepouramountUSDC natifs HyperEVM- L'implémentation déployée de
Exchangedoit être construite avec le jeton USDC natif HyperEVM et les adressesCoreDepositWalletdu réseau cible
Événements et crédit :
event UsdcDeposit(
address indexed account,
address indexed from,
address indexed token,
uint256 amount,
uint32 dstDex
);
L'événement est émis par Exchange après l'appel à CoreDepositWallet.depositFor. Le backend doit faire correspondre cet événement au dépôt HyperCore observé dans le solde de l'Exchange avant de créditer les espèces Hypercall. Le compte Hypercall crédité est le champ explicite account de l'événement.
Exemple :
const usdc = new ethers.Contract(USDC_ADDRESS, ERC20_ABI, signer);
const exchange = new ethers.Contract(EXCHANGE_ADDRESS, EXCHANGE_ABI, signer);
await usdc.approve(EXCHANGE_ADDRESS, amount);
await exchange.depositUsdcFor(accountAddress, amount);
Fonction de dépôt de jetons d'option
function depositOption(address account, address token, uint256 amount) external;
Types de jetons pris en charge :
- Jetons ERC20 d'option (enregistrés dans
OptionRegistry) :msg.value == 0(requis)- Brûle le jeton d'option via
IOptionToken(token).burnFrom(msg.sender, amount) - Émet
Deposit(account, msg.sender, token, amount) - L'indexeur RSM détecte l'événement et crédite la position en options du compte
Exigences :
accountdoit être un compte Hypercall enregistréoptionRegistry != address(0)(doit être défini)msg.senderdoit avoir approuvéExchangepouramount
Exemple (dépôt de jeton d'option) :
const option = new ethers.Contract(OPTION_TOKEN_ADDRESS, ERC20_ABI, signer);
const exchange = new ethers.Contract(EXCHANGE_ADDRESS, EXCHANGE_ABI, signer);
await option.approve(EXCHANGE_ADDRESS, amount);
await exchange.depositOption(accountAddress, OPTION_TOKEN_ADDRESS, amount);
Transfert depuis un compte
Les managers peuvent transférer des jetons de leur compte vers n'importe quel destinataire sur HyperEVM :
function transferFromAccount(address account, address token, address recipient, uint256 amount) external;
Exigences :
msg.sender == managers[account]recipient != address(0)
Cas d'utilisation :
- Finaliser les transferts HyperCore -> HyperEVM initiés par le compte
- Récupérer des fonds d'un compte
- Retirer vers une adresse différente
Exemple :
await exchange.transferFromAccount(
accountAddress,
tokenAddress,
recipientAddress,
amount
);
Intégration avec l'API off-chain
Une fois qu'un compte est créé et qu'un portefeuille API est ajouté :
- Authentification API off-chain : utilisez la clé privée du portefeuille API pour signer des messages EIP-712 (voir Authentification)
- Vérification on-chain : le séquenceur RSM appelle
Exchange.hlRequestOrder(ou similaire) avec votre requête signée - Exécution : l'Exchange vérifie la signature, récupère le portefeuille API, l'associe à votre compte et exécute les actions on-chain
Voir aussi :
- Authentification pour l'authentification API off-chain
Événements
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
event ApiWalletAdded(address indexed account, address indexed manager, address indexed apiWallet);
event ApiWalletRemoved(address indexed account, address indexed manager, address indexed apiWallet);
event Deposit(address indexed account, address indexed from, address indexed token, uint256 amount);
event Withdraw(address indexed account, address indexed to, address indexed token, uint256 amount);
Erreurs
Toutes les erreurs sont définies dans IExchangeBase.sol :
Exchange__AccountManagerNotSet(address account): le compte n'existe pasExchange__ApiWalletAlreadyActive(address apiWallet): portefeuille API déjà utiliséExchange__ApiWalletNotActive(address apiWallet): portefeuille API introuvableExchange__CreationDepositNotMet(uint256 expected):msg.valueinsuffisantExchange__TokenNotSupported(address token): jeton non pris en charge pour le dépôtExchange__MsgValueIncorrect(uint256 expected): incohérence demsg.valueExchange__NotManager(address account, address notManager): l'appelant n'est pas le manager
Considérations de sécurité
-
Sécurité de la clé du manager : la clé du manager contrôle la propriété du compte et la gestion des portefeuilles API. Conservez-la en lieu sûr (portefeuille matériel recommandé).
-
Sécurité des clés des portefeuilles API : les clés des portefeuilles API signent les requêtes de trading. Utilisez des clés distinctes par compte/environnement. Effectuez une rotation régulière.
-
Gestion des nonces : chaque signataire (portefeuille API, manager, RSM) dispose d'un espace de nonces distinct. Suivez les nonces off-chain pour éviter les attaques par rejeu.
-
Activation du compte : les comptes doivent être activés sur HyperCore (dépôt >= 1 $ en HYPE) avant de pouvoir trader des perpétuels. Vérifiez le statut d'activation via l'API HyperCore.
-
Adresses déterministes : les adresses de compte sont déterministes en fonction de l'adresse du manager et du nombre de créations. Utilisez
predictNextAccountpour connaître les adresses avant la création.