온보딩
이 문서는 마켓메이커를 위한 온체인 계정 라이프사이클, 자금 흐름, API 월렛 관리를 설명합니다.
개요
Hypercall은 매니저/에이전트 모델을 사용합니다:
- 매니저(Manager): 계정을 소유하는 EOA (일반적으로 메인 지갑)
- 계정(Account): 자금을 보관하고 온체인 액션을 실행하는 최소 프록시 컨트랙트 (클론)
- API 월렛(API Wallet): 트레이딩 요청에 서명하도록 매니저가 승인한 EOA (에이전트)
모든 온체인 상호작용은 Exchange 컨트랙트를 통해 이루어집니다.
컨트랙트 주소
테스트넷
- Exchange: ``
메인넷
- 세부 정보는 비공개로 공유됩니다.
계정 라이프사이클
1. 기존 계정 확인
새 계정을 생성하기 전에 이미 계정이 있는지 확인하십시오:
function getAccounts(address manager) external view returns (ManagedAccount[] memory);
예제 (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. 계정 생성
msg.sender를 매니저로 하는 새 계정을 생성합니다:
function createAccount() external payable returns (address account);
요구 사항:
accountImpl이 거버넌스에 의해 설정되어 있어야 합니다msg.value >= getCreationDeposit()(HYPE 기준 최소 입금액)creationDepositUsd == 0인 경우 최소 입금액이 필요하지 않습니다- 그렇지 않으면
getCreationDeposit()이 현재 현물 가격을 사용하여 USD 금액을 HYPE로 환산합니다
동작:
accountImpl의 결정론적(deterministic) 최소 프록시(클론)를 배포합니다msg.sender를 계정 매니저로 설정합니다msg.value > 0인 경우, 계정을 대신하여 HYPE 입금을 수행합니다- HYPE를
HYPE_SYSTEM_ADDRESS(HyperCore 브리지)로 전송합니다 - 입금액이 $1 상당의 HYPE 이상이면 HyperCore에서 계정이 활성화됩니다 (활성화 수수료 차감)
- HYPE를
예제 (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
계정 주소 예측:
function predictNextAccount(address manager) external view returns (address);
계정 생성 전에 계정 주소를 알아내는 데 사용할 수 있습니다 (UI/UX에 유용).
3. 계정 이전
매니저는 계정 소유권을 이전할 수 있습니다 (직접 호출은 불가능하며, 생성 시 또는 거버넌스를 통해 발생):
event AccountTransferred(address indexed account, address indexed oldManager, address indexed newManager);
계정 이전 기능은 요청 시 제공됩니다.
API 월렛 관리
API 월렛은 트레이딩 요청에 서명하도록 매니저가 승인한 EOA입니다. 온체인에서 검증되는 EIP-712 메시지에 서명합니다.
API 월렛 추가
function addApiWallet(address account, address apiWallet) external;
요구 사항:
msg.sender == managers[account](계정 매니저여야 함)apiWallet은 다른 계정/매니저에서 활성화되어 있지 않아야 합니다account != address(0)및apiWallet != address(0)
동작:
apiWallet -> account및apiWallet -> manager매핑을 생성합니다- 계정의 API 월렛 집합에
apiWallet을 추가합니다 ApiWalletAdded(account, manager, apiWallet)이벤트를 발생시킵니다
예제:
const tx = await exchange.addApiWallet(accountAddress, apiWalletAddress);
await tx.wait();
API 월렛 제거
function removeApiWallet(address account, address apiWallet) external;
요구 사항:
msg.sender == managers[account]apiWallet이 해당 계정/매니저에서 활성화되어 있어야 합니다
동작:
apiWallet에 대한 매핑을 제거합니다- 계정의 API 월렛 집합에서
apiWallet을 제거합니다 ApiWalletRemoved(account, manager, apiWallet)이벤트를 발생시킵니다
API 월렛 조회
function getAccountByApiWallet(address apiWallet) external view returns (ManagedAccount memory);
apiWallet이 활성화된 경우 해당 계정, 매니저, 그리고 계정의 모든 API 월렛을 반환합니다. 비활성 상태인 경우 제로(zero) 구조체를 반환합니다.
예제:
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);
}
자금 조달 및 입금
Hypercall로 USDC 입금
function depositUsdcFor(address account, uint256 amount) external;
depositUsdcFor는 Hypercall 현금 잔고를 위한 직접 HyperEVM 자금 조달 경로입니다. 네이티브 HyperEVM USDC를 msg.sender에서 Exchange로 전송한 다음, Exchange가 Circle의 CoreDepositWallet을 통해 해당 USDC를 자신의 HyperCore 잔고에 입금합니다.
호출 가능 주체:
- 모든 지갑, 라우터, 솔버 또는 zap 컨트랙트가 이 메서드를 호출할 수 있습니다.
msg.sender가 USDC를 지불합니다.account는 입금이 반영될 Hypercall 계정 또는 지갑입니다. 입금 반영 계정을msg.sender로부터 유추하지 마십시오.
요구 사항:
account != address(0)amount > 0msg.sender는Exchange에amount만큼의 네이티브 HyperEVM USDC 사용을 승인(approve)해야 합니다- 배포된
Exchange구현체는 대상 네트워크의 네이티브 HyperEVM USDC 토큰 및CoreDepositWallet주소로 생성되어 있어야 합니다
이벤트 및 입금 반영:
event UsdcDeposit(
address indexed account,
address indexed from,
address indexed token,
uint256 amount,
uint32 dstDex
);
이 이벤트는 CoreDepositWallet.depositFor 호출 이후 Exchange에서 발생합니다. 백엔드는 Hypercall 현금을 반영하기 전에 이 이벤트를 Exchange 잔고로 관측된 HyperCore 입금과 대조해야 합니다. 입금이 반영되는 Hypercall 계정은 이벤트의 명시적 account 필드입니다.
예제:
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);
옵션 토큰 입금 함수
function depositOption(address account, address token, uint256 amount) external;
지원되는 토큰 유형:
- 옵션 ERC20 토큰 (
OptionRegistry에 등록됨):msg.value == 0(필수)IOptionToken(token).burnFrom(msg.sender, amount)를 통해 옵션 토큰을 소각합니다Deposit(account, msg.sender, token, amount)이벤트를 발생시킵니다- RSM 인덱서가 이벤트를 감지하여 계정의 옵션 포지션에 반영합니다
요구 사항:
account는 등록된 Hypercall 계정이어야 합니다optionRegistry != address(0)(설정되어 있어야 함)msg.sender는Exchange에amount만큼 승인(approve)해야 합니다
예제 (옵션 토큰 입금):
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);
계정에서 자금 전송
매니저는 자신의 계정에서 HyperEVM 상의 모든 수령인에게 토큰을 전송할 수 있습니다:
function transferFromAccount(address account, address token, address recipient, uint256 amount) external;
요구 사항:
msg.sender == managers[account]recipient != address(0)
사용 사례:
- 계정이 시작한 HyperCore -> HyperEVM 전송을 완료
- 계정에서 자금 구출(rescue)
- 다른 주소로 출금
예제:
await exchange.transferFromAccount(
accountAddress,
tokenAddress,
recipientAddress,
amount
);
오프체인 API와의 연동
계정이 생성되고 API 월렛이 추가되면:
- 오프체인 API 인증: API 월렛의 개인 키를 사용하여 EIP-712 메시지에 서명합니다 (인증 참조)
- 온체인 검증: RSM 시퀀서가 서명된 요청과 함께
Exchange.hlRequestOrder(또는 유사 함수)를 호출합니다 - 실행: Exchange가 서명을 검증하고, API 월렛을 복원하여 계정에 매핑한 후 온체인 액션을 실행합니다
참고:
- 오프체인 API 인증에 대해서는 인증을 참조하십시오
이벤트
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);
오류
모든 오류는 IExchangeBase.sol에 정의되어 있습니다:
Exchange__AccountManagerNotSet(address account): 계정이 존재하지 않음Exchange__ApiWalletAlreadyActive(address apiWallet): API 월렛이 이미 사용 중임Exchange__ApiWalletNotActive(address apiWallet): API 월렛을 찾을 수 없음Exchange__CreationDepositNotMet(uint256 expected):msg.value부족Exchange__TokenNotSupported(address token): 입금이 지원되지 않는 토큰Exchange__MsgValueIncorrect(uint256 expected):msg.value불일치Exchange__NotManager(address account, address notManager): 호출자가 매니저가 아님
보안 고려 사항
-
매니저 키 보안: 매니저 키는 계정 소유권과 API 월렛 관리를 제어합니다. 안전하게 보관하십시오 (하드웨어 지갑 권장).
-
API 월렛 키 보안: API 월렛 키는 트레이딩 요청에 서명합니다. 계정/환경별로 별도의 키를 사용하십시오. 정기적으로 교체하십시오.
-
논스(Nonce) 관리: 각 서명자(API 월렛, 매니저, RSM)는 별도의 논스 공간을 갖습니다. 재전송(replay) 공격을 방지하기 위해 오프체인에서 논스를 추적하십시오.
-
계정 활성화: 무기한 계약을 거래하려면 먼저 HyperCore에서 계정이 활성화되어 있어야 합니다 ($1 이상의 HYPE 입금). HyperCore API를 통해 활성화 상태를 확인하십시오.
-
결정론적 주소: 계정 주소는 매니저 주소와 생성 횟수에 따라 결정론적으로 정해집니다. 생성 전에 주소를 알려면
predictNextAccount를 사용하십시오.