Trang này được dịch tự động. Bản gốc tiếng Anh là phiên bản chính thức. Đọc bằng tiếng Anh
Chuyển đến nội dung chính

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:

  • accountImpl phải được thiết lập bởi governance
  • msg.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

Hành vi:

  • Triển khai một minimal proxy (clone) có tính xác định của accountImpl
  • Đặt msg.sender là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ừ)

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)
  • apiWallet không được đang hoạt động cho bất kỳ tài khoản/manager nào khác
  • account != address(0)apiWallet != address(0)

Hành vi:

  • Ánh xạ apiWallet -> accountapiWallet -> manager
  • Thêm apiWallet và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]
  • apiWallet phả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 apiWallet khỏ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.sender là bên trả USDC.
  • account là 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 > 0
  • msg.sender phải approve cho Exchange số lượng amount USDC 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ỉ CoreDepositWallet cho 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ợ:

  1. 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:

  • account phải là một tài khoản Hypercall đã đăng ký
  • optionRegistry != address(0) (phải được thiết lập)
  • msg.sender phải đã approve cho Exchange số lượng amount

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:

  1. 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)
  2. 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
  3. 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:

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ại
  • Exchange__ApiWalletAlreadyActive(address apiWallet): Ví API đang được sử dụng
  • Exchange__ApiWalletNotActive(address apiWallet): Không tìm thấy ví API
  • Exchange__CreationDepositNotMet(uint256 expected): msg.value không đủ
  • Exchange__TokenNotSupported(address token): Token không được hỗ trợ để nạp
  • Exchange__MsgValueIncorrect(uint256 expected): msg.value không khớp
  • Exchange__NotManager(address account, address notManager): Người gọi không phải là manager

Các lưu ý về bảo mật

  1. 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).

  2. 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ỳ.

  3. 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).

  4. 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.

  5. Đị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.