Skip to main content

Onboarding

This page covers the on-chain Account lifecycle, funding, and API wallet management. Addresses are on Contracts, and GET /exchange-info returns the live Exchange, Factory, and deposit router addresses.

Overview​

Hypercall uses a manager and API wallet model:

  • Manager: the EOA that creates and owns the Account (usually your main wallet).
  • Account: a BeaconProxy contract that holds your HyperCore balances and positions and executes signed directives.
  • API wallet: an EOA the manager authorizes on the Account to sign orders and cancels.

Accounts are created by the Factory. Signed directives are submitted to the Exchange by Hypercall's sequencer; you sign, Hypercall submits.

Account Lifecycle​

1. Check Existing Accounts​

// Exchange
function getAccounts(address manager) external view returns (ManagedAccount[] memory);

struct ManagedAccount {
address account;
address manager;
ApiWallet[] apiWallets; // { bytes32 name; address addr; }
}

2. Create Account​

// Factory
function createAccount(uint96 salt) external payable returns (address account);
function getCreationDeposit() external view returns (uint256); // in HYPE wei
function predictAccount(address manager, uint96 salt) external view returns (address account, bool exists);

Requirements:

  • msg.value >= getCreationDeposit(). The Factory sets the creation deposit in USD and converts it to HYPE at the HyperCore spot price, rounded up. On mainnet it is currently $1.50.
  • If a creation filter is configured, it must allow msg.sender.

Behavior:

  • Deploys the Account with CREATE2 from the manager address and salt, so the address is known in advance through predictAccount.
  • Registers the Account with the Exchange and sets msg.sender as manager.
  • Bridges any msg.value to the Account on HyperCore as HYPE. A deposit worth at least $1 activates the Account on HyperCore.
const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);
const salt = 0n;
const [predicted] = await factory.predictAccount(managerAddress, salt);
const value = await factory.getCreationDeposit();
await (await factory.createAccount(salt, { value })).wait();

3. Manager Changes​

There is no manager transfer function. The manager can change only when an on-chain liquidation auction resolves, and no auctioneer is configured on mainnet. On a change the Exchange emits AccountTransferred(account, oldManager, newManager) and the Account emits ManagerSet(oldManager, newManager).

API Wallet Management​

API wallets are stored on the Account, keyed by a bytes32 name. They sign directives in the HypercallApiSign EIP-712 domain. See EIP-712 Signing.

Add, Replace, or Remove​

Submit an hc_update_api_wallet directive signed by the manager in the HypercallManagerSign domain:

HCUpdateApiWallet(address account,uint64 nonce,UpdateApiWallet action)UpdateApiWallet(bytes32 name,address addr)
  • A new name adds a wallet. An existing name replaces its wallet.
  • addr = 0x0 removes the wallet under name.
  • The API wallet cannot be the manager and cannot already be active on the Account.

Post it to POST /v1/actions/hc_update_api_wallet with account, nonce, action ({ "name": "0x...", "addr": "0x..." }), and signature. POST /v1/actions/hc_update_api_wallet/typed-data returns the exact typed data to sign. Poll GET /v1/directives/{directive_id} for the on-chain result. The Account emits ApiWalletUpdated(name, addr).

Query​

// Account
function getApiWallets() external view returns (ApiWallet[] memory);
function getApiWallet(bytes32 name) external view returns (address);
function isApiWalletActive(address addr) external view returns (bool);

Funding & Deposits​

USDC Deposit To Hypercall​

// Exchange
function depositUsdcFor(address account, uint256 amount) external;

depositUsdcFor is the direct HyperEVM funding path for Hypercall cash. It pulls native HyperEVM USDC from msg.sender into the Exchange, then deposits it into the Exchange's HyperCore balance through Circle's CoreDepositWallet.

Who may call it:

  • Any wallet, router, solver, or zap contract.
  • msg.sender pays the USDC.
  • account is the Hypercall account or wallet to credit. Do not infer the credited account from msg.sender.

Requirements:

  • account != address(0) and amount > 0
  • msg.sender has approved the Exchange for amount USDC
event UsdcDeposit(
address indexed account,
address indexed from,
address indexed token,
uint256 amount,
uint32 dstDex
);

Hypercall credits cash only after matching this event to the observed HyperCore deposit. The credited account is the account field.

await usdc.approve(EXCHANGE_ADDRESS, amount);
await exchange.depositUsdcFor(accountAddress, amount);

The Router's deposit(account, token, amount, isPerp) is the general helper used by the app for USDC, spot tokens, and option tokens.

Option Token Deposit​

// Exchange
function depositOption(address account, address token, uint256 amount) external;
  • account must be a registered Hypercall Account.
  • token must be a supported option in the Option Registry.
  • Burns amount from msg.sender (approve the Exchange first) and emits Deposit(account, msg.sender, token, amount), which the engine credits.

Transfer Out of the Account​

// Account, manager only
function transferTo(address recipient, address token, uint256 amount) external;

Moves native HYPE (token = 0x0) or an ERC20 held by the Account on HyperEVM to recipient. Use it to finish HyperCore to HyperEVM transfers or to sweep the Account. Not available while the Account is in liquidation.

Builder Approval for Perps​

// Account, manager only
function approveZeroFeeBuilder(address builder) external;

Approves a Hyperliquid builder for the Account at a 0% maximum fee. Every Hypercall perp order carries the Hypercall builder code, so call this once with the hl_builder_address from GET /exchange-info before the first perp order. The app does this in its Enable trading step.

Events​

// Exchange
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
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);
// Factory
event AccountCreated(address indexed account, address indexed manager);
// Account
event ApiWalletUpdated(bytes32 indexed name, address indexed addr);
event ManagerSet(address indexed oldManager, address indexed newManager);

Errors​

  • Factory__CreationDepositNotMet(uint256 expected): msg.value below the creation deposit
  • Factory__CreationNotAllowed(): blocked by the creation filter
  • Exchange__AccountDoesNotExist(address account): not a registered Account
  • Exchange__TokenNotSupported(address token): not a supported option token
  • Account__NotManager(address addr): caller or signer is not the manager
  • Account__ApiWalletNotActive(address addr): signer is not an active API wallet
  • Account__ApiWalletAlreadyActive(address addr): API wallet already on the Account
  • Account__ApiWalletIsManager(): the manager cannot be its own API wallet
  • Account__NonceAlreadyUsed(address signer, uint256 nonce): nonce reused
  • Account__LiquidationInProgress(): action blocked during liquidation

Security Considerations​

  1. Manager key: controls API wallets, transfers out, and builder approval. Use a hardware wallet.
  2. API wallet keys: sign orders and cancels only. Use separate keys per system and rotate them.
  3. Nonces: each signer has its own nonce space. Use millisecond timestamps and track them off-chain.
  4. Activation: the Account must be activated on HyperCore (at least $1 of HYPE deposited) before it can trade perps.