Onboarding
Tài liệu này mô tả vòng đời tài khoản on-chain, các luồng nạp tiền, và quản lý ví API dành cho các Nhà tạo lập thị trường.
Tổng quan
Hypercall sử dụng mô hình manager/agent:
- Manager: EOA sở hữu tài khoản (thường là ví chính của bạn)
- Account: Một hợp đồng minimal proxy (clone) giữ tiền và thực thi các hành động on-chain
- Ví API: Một EOA được manager ủy quyền để ký các yêu cầu giao dịch (agent)
Tất cả các tương tác on-chain đều diễn ra thông qua hợp đồng Exchange.
Địa chỉ hợp đồng
Testnet
- Exchange: ``
Mạng chính
- Chi tiết được chia sẻ riêng.
Vòng đời tài khoản
1. Kiểm tra tài khoản hiện có
Trước khi tạo tài khoản mới, hãy kiểm tra xem bạn đã có tài khoản chưa:
function getAccounts(address manager) external view returns (ManagedAccount[] memory);
Ví dụ (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. Tạo tài khoản
Tạo tài khoản mới với msg.sender là manager:
function createAccount() external payable returns (address account);
Yêu cầu:
accountImplphải được thiết lập bởi governancemsg.value >= getCreationDeposit()(khoản nạp tối thiểu bằng HYPE)- Nếu
creationDepositUsd == 0, không yêu cầu khoản nạp tối thiểu - Ngược lại,
getCreationDeposit()sẽ quy đổi số tiền USD sang HYPE theo giá spot hiện tại
- Nếu
Hành vi:
- Triển khai một minimal proxy (clone) có tính xác định của
accountImpl - Đặt
msg.senderlàm manager của tài khoản - Nếu
msg.value > 0, thực hiện nạp HYPE thay mặt cho tài khoản- Chuyển HYPE tới
HYPE_SYSTEM_ADDRESS(cầu nối HyperCore) - Nếu khoản nạp >= $1 giá trị HYPE, tài khoản sẽ được kích hoạt trên HyperCore (phí kích hoạt sẽ được khấu trừ)
- Chuyển HYPE tới
Ví dụ (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
Dự đoán địa chỉ tài khoản:
function predictNextAccount(address manager) external view returns (address);
Sử dụng hàm này để biết địa chỉ tài khoản trước khi tạo (hữu ích cho UI/UX).
3. Chuyển nhượng tài khoản
Manager có thể chuyển nhượng quyền sở hữu tài khoản (không thể gọi trực tiếp; chỉ xảy ra trong quá trình tạo hoặc thông qua governance):
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
Chức năng chuyển nhượng tài khoản được cung cấp theo yêu cầu.
Quản lý ví API
Ví API là các EOA được manager ủy quyền để ký các yêu cầu giao dịch. Chúng ký các thông điệp EIP-712 và các thông điệp này được xác minh on-chain.
Thêm ví API
function addApiWallet(address account, address apiWallet) external;
Yêu cầu:
msg.sender == managers[account](phải là manager của tài khoản)apiWalletkhông được đang hoạt động cho bất kỳ tài khoản/manager nào khácaccount != address(0)vàapiWallet != address(0)
Hành vi:
- Ánh xạ
apiWallet -> accountvàapiWallet -> manager - Thêm
apiWalletvào tập hợp ví API của tài khoản - Phát ra sự kiện
ApiWalletAdded(account, manager, apiWallet)
Ví dụ:
const tx = await exchange.addApiWallet(accountAddress, apiWalletAddress);
await tx.wait();
Xóa ví API
function removeApiWallet(address account, address apiWallet) external;
Yêu cầu:
msg.sender == managers[account]apiWalletphải đang hoạt động cho tài khoản/manager này
Hành vi:
- Xóa các ánh xạ của
apiWallet - Xóa
apiWalletkhỏi tập hợp ví API của tài khoản - Phát ra sự kiện
ApiWalletRemoved(account, manager, apiWallet)
Truy vấn ví API
function getAccountByApiWallet(address apiWallet) external view returns (ManagedAccount memory);
Trả về tài khoản, manager, và tất cả các ví API của tài khoản nếu apiWallet đang hoạt động. Trả về struct rỗng (zero struct) nếu không hoạt động.
Ví dụ:
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);
}
Nạp tiền & Ký gửi
Nạp USDC vào Hypercall
function depositUsdcFor(address account, uint256 amount) external;
depositUsdcFor là kênh nạp tiền trực tiếp từ HyperEVM cho số dư tiền mặt Hypercall. Hàm này chuyển USDC gốc trên HyperEVM từ msg.sender vào Exchange, sau đó Exchange nạp số USDC này vào số dư HyperCore của nó thông qua CoreDepositWallet của Circle.
Ai có thể gọi hàm này:
- Bất kỳ ví, router, solver, hoặc hợp đồng zap nào đều có thể gọi phương thức này.
msg.senderlà bên trả USDC.accountlà tài khoản hoặc ví Hypercall được ghi có. Không được suy luận tài khoản được ghi có từmsg.sender.
Yêu cầu:
account != address(0)amount > 0msg.senderphải approve choExchangesố lượngamountUSDC gốc trên HyperEVM- Bản triển khai
Exchangeđã deploy phải được khởi tạo với địa chỉ token USDC gốc trên HyperEVM và địa chỉCoreDepositWalletcho mạng đích
Sự kiện và ghi có:
event UsdcDeposit(
address indexed account,
address indexed from,
address indexed token,
uint256 amount,
uint32 dstDex
);
Sự kiện này được phát ra bởi Exchange sau lệnh gọi CoreDepositWallet.depositFor. Backend phải khớp sự kiện này với khoản nạp HyperCore được quan sát vào số dư của Exchange trước khi ghi có tiền mặt Hypercall. Tài khoản Hypercall được ghi có chính là trường sự kiện account được chỉ định rõ ràng.
Ví dụ:
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);
Hàm nạp token quyền chọn
function depositOption(address account, address token, uint256 amount) external;
Các loại token được hỗ trợ:
- Token ERC20 quyền chọn (được đăng ký trong
OptionRegistry):msg.value == 0(bắt buộc)- Đốt (burn) token quyền chọn thông qua
IOptionToken(token).burnFrom(msg.sender, amount) - Phát ra sự kiện
Deposit(account, msg.sender, token, amount) - RSM indexer sẽ ghi nhận sự kiện và ghi có vị thế quyền chọn cho tài khoản
Yêu cầu:
accountphải là một tài khoản Hypercall đã đăng kýoptionRegistry != address(0)(phải được thiết lập)msg.senderphải đã approve choExchangesố lượngamount
Ví dụ (nạp token quyền chọn):
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);
Chuyển tiền từ tài khoản
Manager có thể chuyển token từ tài khoản của họ tới bất kỳ người nhận nào trên HyperEVM:
function transferFromAccount(address account, address token, address recipient, uint256 amount) external;
Yêu cầu:
msg.sender == managers[account]recipient != address(0)
Trường hợp sử dụng:
- Hoàn tất các giao dịch chuyển từ HyperCore -> HyperEVM do tài khoản khởi tạo
- Cứu tiền khỏi một tài khoản
- Rút tiền tới một địa chỉ khác
Ví dụ:
await exchange.transferFromAccount(
accountAddress,
tokenAddress,
recipientAddress,
amount
);
Tích hợp với API Off-Chain
Sau khi tài khoản được tạo và ví API đã được thêm:
- Xác thực API off-chain: Sử dụng khóa riêng tư (private key) của ví API để ký các thông điệp EIP-712 (xem Authentication)
- Xác minh on-chain: RSM Sequencer gọi
Exchange.hlRequestOrder(hoặc tương tự) với yêu cầu đã được ký của bạn - Thực thi: Exchange xác minh chữ ký, khôi phục ví API, ánh xạ nó tới tài khoản của bạn, và thực thi các hành động on-chain
Xem thêm:
- Authentication về xác thực API off-chain
Sự kiện
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);
Lỗi
Tất cả các lỗi được định nghĩa trong IExchangeBase.sol:
Exchange__AccountManagerNotSet(address account): Tài khoản không tồn tạiExchange__ApiWalletAlreadyActive(address apiWallet): Ví API đang được sử dụngExchange__ApiWalletNotActive(address apiWallet): Không tìm thấy ví APIExchange__CreationDepositNotMet(uint256 expected):msg.valuekhông đủExchange__TokenNotSupported(address token): Token không được hỗ trợ để nạpExchange__MsgValueIncorrect(uint256 expected):msg.valuekhông khớpExchange__NotManager(address account, address notManager): Người gọi không phải là manager
Các lưu ý về bảo mật
-
Bảo mật khóa Manager: Khóa manager kiểm soát quyền sở hữu tài khoản và quản lý ví API. Hãy lưu trữ an toàn (khuyến nghị dùng ví phần cứng).
-
Bảo mật khóa ví API: Khóa của ví API dùng để ký các yêu cầu giao dịch. Sử dụng khóa riêng cho từng tài khoản/môi trường. Xoay vòng khóa định kỳ.
-
Quản lý Nonce: Mỗi bên ký (ví API, manager, RSM) có một không gian nonce riêng. Theo dõi nonce ở off-chain để tránh các cuộc tấn công phát lại (replay attack).
-
Kích hoạt tài khoản: Tài khoản phải được kích hoạt trên HyperCore (khoản nạp >= $1 HYPE) trước khi có thể giao dịch perp. Kiểm tra trạng thái kích hoạt thông qua HyperCore API.
-
Địa chỉ có tính xác định: Địa chỉ tài khoản là xác định dựa trên địa chỉ manager và số lần tạo. Sử dụng
predictNextAccountđể biết địa chỉ trước khi tạo.