Onboarding
This document describes the on-chain account lifecycle, funding flows, and API wallet management for Market Makers.
Overview
HyperCall uses a manager/agent model:
- Manager: The EOA that owns the account (typically your main wallet)
- Account: A minimal proxy contract (clone) that holds funds and executes on-chain actions
- API Wallet: An EOA authorized by the manager to sign trading requests (agent)
All on-chain interactions occur via the Exchange contract.
Account Lifecycle
1. Check Existing Accounts
Before creating a new account, check if you already have accounts:
function getAccounts(address manager) external view returns (ManagedAccount[] memory);
Example (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. Create Account
Creates a new account with msg.sender as the manager:
function createAccount() external payable returns (address account);
Requirements:
accountImplmust be set by governancemsg.value >= getCreationDeposit()(minimum deposit in HYPE)- If
creationDepositUsd == 0, no minimum deposit is required - Otherwise,
getCreationDeposit()converts USD amount to HYPE using current spot price
- If
Behavior:
- Deploys a deterministic minimal proxy (clone) of
accountImpl - Sets
msg.senderas the account manager - If
msg.value > 0, performs a HYPE deposit on behalf of the account- Transfers HYPE to
HYPE_SYSTEM_ADDRESS(HyperCore bridge) - If deposit >= $1 worth of HYPE, account is activated on HyperCore (activation fee deducted)
- Transfers HYPE to
Example (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
Predict Account Address:
function predictNextAccount(address manager) external view returns (address);
Use this to know the account address before creation (useful for UI/UX).
3. Account Transfer
Managers can transfer account ownership (not directly callable; occurs during creation or via governance):
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
Account transfer functionality is provided on request.
API Wallet Management
API wallets are EOAs authorized by the manager to sign trading requests. They sign EIP-712 messages that are verified on-chain.
Add API Wallet
function addApiWallet(address account, address apiWallet) external;
Requirements:
msg.sender == managers[account](must be the account manager)apiWalletmust not be active for any other account/manageraccount != address(0)andapiWallet != address(0)
Behavior:
- Maps
apiWallet -> accountandapiWallet -> manager - Adds
apiWalletto the account's API wallet set - Emits
ApiWalletAdded(account, manager, apiWallet)
Example:
const tx = await exchange.addApiWallet(accountAddress, apiWalletAddress);
await tx.wait();
Remove API Wallet
function removeApiWallet(address account, address apiWallet) external;
Requirements:
msg.sender == managers[account]apiWalletmust be active for this account/manager
Behavior:
- Removes mappings for
apiWallet - Removes
apiWalletfrom the account's API wallet set - Emits
ApiWalletRemoved(account, manager, apiWallet)
Query API Wallets
function getAccountByApiWallet(address apiWallet) external view returns (ManagedAccount memory);
Returns the account, manager, and all API wallets for the account if apiWallet is active. Returns zero struct if inactive.
Example:
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);
}
Funding & Deposits
Deposit Function
function deposit(address account, address token, uint256 amount) external payable;
Supported Token Types:
-
Native HYPE (
token == address(0)ortoken == NATIVE_TOKEN):msg.value == amount(required)- Transfers HYPE to
HYPE_SYSTEM_ADDRESS(HyperCore bridge) - Increases account's Spot HYPE balance
- Used for account activation if >= $1 worth
-
Quote Token (
token == QUOTE_TOKEN, typically USDC):msg.value == 0(required)- Transfers ERC20 from
msg.sendertoaccount - Calls
account.depositToCore(CORE_DEPOSIT, QUOTE_TOKEN, amount) - Increases account's Perp available margin
-
ERC20 Spot Tokens (registered in
TOKEN_REGISTRY):msg.value == 0(required)- Transfers ERC20 from
msg.sendertoaccount - Transfers to system address
ERC20_SYSTEM_ADDRESS + tokenIndex - Increases account's Spot token balance
-
Option ERC20 Tokens (registered in
OptionRegistry):msg.value == 0(required)- Burns the option token via
IOptionToken(token).burnFrom(msg.sender, amount) - Emits
Deposit(account, msg.sender, token, amount) - RSM indexer picks up the event and credits the account's option position
Requirements:
managers[account] != address(0)(account must exist)optionRegistry != address(0)(must be set)- For ERC20 tokens:
msg.sendermust have approvedExchangeforamount
Example (USDC deposit):
const usdc = new ethers.Contract(USDC_ADDRESS, ERC20_ABI, signer);
const exchange = new ethers.Contract(EXCHANGE_ADDRESS, EXCHANGE_ABI, signer);
// Approve first
await usdc.approve(EXCHANGE_ADDRESS, amount);
// Then deposit
await exchange.deposit(accountAddress, USDC_ADDRESS, amount);
Example (HYPE deposit):
await exchange.deposit(accountAddress, ethers.ZeroAddress, amount, { value: amount });
Transfer From Account
Managers can transfer tokens from their account to any recipient on HyperEVM:
function transferFromAccount(address account, address token, address recipient, uint256 amount) external;
Requirements:
msg.sender == managers[account]recipient != address(0)
Use Cases:
- Complete HyperCore -> HyperEVM transfers initiated by the account
- Rescue funds from an account
- Withdraw to a different address
Example:
await exchange.transferFromAccount(
accountAddress,
tokenAddress,
recipientAddress,
amount
);
Integration with Off-Chain API
Once an account is created and an API wallet is added:
- Off-chain API authentication: Use the API wallet's private key to sign EIP-712 messages (see Authentication)
- On-chain verification: The RSM Sequencer calls
Exchange.hlRequestOrder(or similar) with your signed request - Execution: The Exchange verifies the signature, recovers the API wallet, maps it to your account, and executes on-chain actions
See Also:
- Authentication for off-chain API authentication
Events
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);
Errors
All errors are defined in IExchangeBase.sol:
Exchange__AccountManagerNotSet(address account): Account doesn't existExchange__ApiWalletAlreadyActive(address apiWallet): API wallet already in useExchange__ApiWalletNotActive(address apiWallet): API wallet not foundExchange__CreationDepositNotMet(uint256 expected): Insufficientmsg.valueExchange__TokenNotSupported(address token): Token not supported for depositExchange__MsgValueIncorrect(uint256 expected):msg.valuemismatchExchange__NotManager(address account, address notManager): Caller is not the manager
Security Considerations
-
Manager Key Security: The manager key controls account ownership and API wallet management. Store securely (hardware wallet recommended).
-
API Wallet Key Security: API wallet keys sign trading requests. Use separate keys per account/environment. Rotate regularly.
-
Nonce Management: Each signer (API wallet, manager, RSM) has a separate nonce space. Track nonces off-chain to avoid replay attacks.
-
Account Activation: Accounts must be activated on HyperCore (deposit >= $1 HYPE) before they can trade perps. Check activation status via HyperCore API.
-
Deterministic Addresses: Account addresses are deterministic based on manager address and creation count. Use
predictNextAccountto know addresses before creation.