Onboarding
Este documento descreve o ciclo de vida da conta on-chain, os fluxos de financiamento e o gerenciamento de API wallets para Market Makers.
Visão Geral
A Hypercall usa um modelo manager/agent:
- Manager: A EOA que possui a conta (normalmente sua carteira principal)
- Account: Um contrato de proxy mínimo (clone) que mantém os fundos e executa ações on-chain
- API Wallet: Uma EOA autorizada pelo manager a assinar requisições de trading (agent)
Todas as interações on-chain ocorrem por meio do contrato Exchange.
Endereços dos Contratos
Testnet
- Exchange: ``
Mainnet
- Detalhes são compartilhados de forma privada.
Ciclo de Vida da Conta
1. Verificar Contas Existentes
Antes de criar uma nova conta, verifique se você já possui contas:
function getAccounts(address manager) external view returns (ManagedAccount[] memory);
Exemplo (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. Criar Conta
Cria uma nova conta com msg.sender como manager:
function createAccount() external payable returns (address account);
Requisitos:
accountImpldeve ser definido pela governançamsg.value >= getCreationDeposit()(depósito mínimo em HYPE)- Se
creationDepositUsd == 0, nenhum depósito mínimo é exigido - Caso contrário,
getCreationDeposit()converte o valor em USD para HYPE usando o preço spot atual
- Se
Comportamento:
- Faz o deploy de um proxy mínimo determinístico (clone) de
accountImpl - Define
msg.sendercomo manager da conta - Se
msg.value > 0, realiza um depósito de HYPE em nome da conta- Transfere HYPE para
HYPE_SYSTEM_ADDRESS(bridge do HyperCore) - Se o depósito for >= $1 em HYPE, a conta é ativada no HyperCore (a taxa de ativação é deduzida)
- Transfere HYPE para
Exemplo (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
Prever o Endereço da Conta:
function predictNextAccount(address manager) external view returns (address);
Use isso para saber o endereço da conta antes da criação (útil para UI/UX).
3. Transferência de Conta
Managers podem transferir a propriedade da conta (não é chamável diretamente; ocorre durante a criação ou via governança):
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
A funcionalidade de transferência de conta é disponibilizada mediante solicitação.
Gerenciamento de API Wallets
API wallets são EOAs autorizadas pelo manager a assinar requisições de trading. Elas assinam mensagens EIP-712 que são verificadas on-chain.
Adicionar API Wallet
function addApiWallet(address account, address apiWallet) external;
Requisitos:
msg.sender == managers[account](deve ser o manager da conta)apiWalletnão pode estar ativa para nenhuma outra conta/manageraccount != address(0)eapiWallet != address(0)
Comportamento:
- Mapeia
apiWallet -> accounteapiWallet -> manager - Adiciona
apiWalletao conjunto de API wallets da conta - Emite
ApiWalletAdded(account, manager, apiWallet)
Exemplo:
const tx = await exchange.addApiWallet(accountAddress, apiWalletAddress);
await tx.wait();
Remover API Wallet
function removeApiWallet(address account, address apiWallet) external;
Requisitos:
msg.sender == managers[account]apiWalletdeve estar ativa para esta conta/manager
Comportamento:
- Remove os mapeamentos de
apiWallet - Remove
apiWalletdo conjunto de API wallets da conta - Emite
ApiWalletRemoved(account, manager, apiWallet)
Consultar API Wallets
function getAccountByApiWallet(address apiWallet) external view returns (ManagedAccount memory);
Retorna a conta, o manager e todas as API wallets da conta se apiWallet estiver ativa. Retorna um struct zerado se inativa.
Exemplo:
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);
}
Financiamento e Depósitos
Depósito de USDC na Hypercall
function depositUsdcFor(address account, uint256 amount) external;
depositUsdcFor é o caminho de financiamento direto via HyperEVM para os saldos em caixa da Hypercall. Ele transfere USDC nativo da HyperEVM de msg.sender para o Exchange, e então o Exchange deposita esse USDC em seu saldo no HyperCore por meio da CoreDepositWallet da Circle.
Quem pode chamar:
- Qualquer carteira, roteador, solver ou contrato zap pode chamar este método.
msg.senderpaga o USDC.accounté a conta ou carteira Hypercall a ser creditada. Não infira a conta creditada a partir demsg.sender.
Requisitos:
account != address(0)amount > 0msg.senderdeve aprovar oExchangeparaamountde USDC nativo da HyperEVM- A implementação de
Exchangeimplantada deve ser construída com o token USDC nativo da HyperEVM e os endereços daCoreDepositWalletpara a rede alvo
Eventos e crédito:
event UsdcDeposit(
address indexed account,
address indexed from,
address indexed token,
uint256 amount,
uint32 dstDex
);
O evento é emitido pelo Exchange após a chamada de CoreDepositWallet.depositFor. O backend deve corresponder esse evento ao depósito observado no HyperCore no saldo do Exchange antes de creditar o caixa da Hypercall. A conta Hypercall creditada é o campo explícito account do evento.
Exemplo:
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);
Função de Depósito de Tokens de Opção
function depositOption(address account, address token, uint256 amount) external;
Tipos de Token Suportados:
- Tokens ERC20 de Opção (registrados no
OptionRegistry):msg.value == 0(obrigatório)- Queima o token de opção via
IOptionToken(token).burnFrom(msg.sender, amount) - Emite
Deposit(account, msg.sender, token, amount) - O indexador do RSM captura o evento e credita a posição de opção da conta
Requisitos:
accountdeve ser uma conta Hypercall registradaoptionRegistry != address(0)(deve estar definido)msg.senderdeve ter aprovado oExchangeparaamount
Exemplo (depósito de token de opção):
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);
Transferir da Conta
Managers podem transferir tokens de sua conta para qualquer destinatário na HyperEVM:
function transferFromAccount(address account, address token, address recipient, uint256 amount) external;
Requisitos:
msg.sender == managers[account]recipient != address(0)
Casos de Uso:
- Concluir transferências HyperCore -> HyperEVM iniciadas pela conta
- Resgatar fundos de uma conta
- Sacar para um endereço diferente
Exemplo:
await exchange.transferFromAccount(
accountAddress,
tokenAddress,
recipientAddress,
amount
);
Integração com a API Off-Chain
Depois que uma conta for criada e uma API wallet for adicionada:
- Autenticação na API off-chain: Use a chave privada da API wallet para assinar mensagens EIP-712 (veja Autenticação)
- Verificação on-chain: O RSM Sequencer chama
Exchange.hlRequestOrder(ou similar) com sua requisição assinada - Execução: O Exchange verifica a assinatura, recupera a API wallet, mapeia-a para sua conta e executa as ações on-chain
Veja Também:
- Autenticação para autenticação na API off-chain
Eventos
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);
Erros
Todos os erros estão definidos em IExchangeBase.sol:
Exchange__AccountManagerNotSet(address account): A conta não existeExchange__ApiWalletAlreadyActive(address apiWallet): API wallet já em usoExchange__ApiWalletNotActive(address apiWallet): API wallet não encontradaExchange__CreationDepositNotMet(uint256 expected):msg.valueinsuficienteExchange__TokenNotSupported(address token): Token não suportado para depósitoExchange__MsgValueIncorrect(uint256 expected):msg.valuedivergenteExchange__NotManager(address account, address notManager): O chamador não é o manager
Considerações de Segurança
-
Segurança da Chave do Manager: A chave do manager controla a propriedade da conta e o gerenciamento das API wallets. Armazene com segurança (hardware wallet recomendada).
-
Segurança da Chave da API Wallet: As chaves das API wallets assinam requisições de trading. Use chaves separadas por conta/ambiente. Faça a rotação regularmente.
-
Gerenciamento de Nonces: Cada signatário (API wallet, manager, RSM) tem um espaço de nonce separado. Rastreie os nonces off-chain para evitar ataques de replay.
-
Ativação da Conta: As contas devem ser ativadas no HyperCore (depósito >= $1 em HYPE) antes de poderem negociar perps. Verifique o status de ativação via API do HyperCore.
-
Endereços Determinísticos: Os endereços das contas são determinísticos com base no endereço do manager e no contador de criação. Use
predictNextAccountpara saber os endereços antes da criação.